diff --git a/src/MainDemo.Wpf/Toggles.xaml b/src/MainDemo.Wpf/Toggles.xaml
index 2700d706d9..475abb25a5 100644
--- a/src/MainDemo.Wpf/Toggles.xaml
+++ b/src/MainDemo.Wpf/Toggles.xaml
@@ -4,6 +4,8 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:domain="clr-namespace:MaterialDesignDemo.Domain"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:sharedCbs="clr-namespace:MaterialDesignDemo.Shared.Examples.CheckBoxExamples;assembly=MaterialDesignDemo.Shared"
+ xmlns:sharedRbs="clr-namespace:MaterialDesignDemo.Shared.Examples.RadioButtonExamples;assembly=MaterialDesignDemo.Shared"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:smtx="clr-namespace:ShowMeTheXAML;assembly=ShowMeTheXAML"
d:DesignHeight="4096"
@@ -223,6 +225,8 @@
+
+
@@ -289,6 +293,8 @@
+
+
diff --git a/src/MaterialDesign3.Demo.Wpf/Toggles.xaml b/src/MaterialDesign3.Demo.Wpf/Toggles.xaml
index 44da7c0e82..8fc2b1455b 100644
--- a/src/MaterialDesign3.Demo.Wpf/Toggles.xaml
+++ b/src/MaterialDesign3.Demo.Wpf/Toggles.xaml
@@ -4,6 +4,8 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:domain="clr-namespace:MaterialDesign3Demo.Domain"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
+ xmlns:sharedCbs="clr-namespace:MaterialDesignDemo.Shared.Examples.CheckBoxExamples;assembly=MaterialDesignDemo.Shared"
+ xmlns:sharedRbs="clr-namespace:MaterialDesignDemo.Shared.Examples.RadioButtonExamples;assembly=MaterialDesignDemo.Shared"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:smtx="clr-namespace:ShowMeTheXAML;assembly=ShowMeTheXAML"
d:DesignHeight="700"
@@ -204,6 +206,8 @@
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/MaterialDesignDemo.Shared/Examples/CheckBoxExamples/ContentPlacementExample.xaml.cs b/src/MaterialDesignDemo.Shared/Examples/CheckBoxExamples/ContentPlacementExample.xaml.cs
new file mode 100644
index 0000000000..58d3241884
--- /dev/null
+++ b/src/MaterialDesignDemo.Shared/Examples/CheckBoxExamples/ContentPlacementExample.xaml.cs
@@ -0,0 +1,12 @@
+namespace MaterialDesignDemo.Shared.Examples.CheckBoxExamples;
+
+///
+/// Interaction logic for ContentPlacementExample.xaml
+///
+public partial class ContentPlacementExample : UserControl
+{
+ public ContentPlacementExample()
+ {
+ InitializeComponent();
+ }
+}
diff --git a/src/MaterialDesignDemo.Shared/Examples/RadioButtonExamples/ContentPlacementExample.xaml b/src/MaterialDesignDemo.Shared/Examples/RadioButtonExamples/ContentPlacementExample.xaml
new file mode 100644
index 0000000000..fb7dc7a7d9
--- /dev/null
+++ b/src/MaterialDesignDemo.Shared/Examples/RadioButtonExamples/ContentPlacementExample.xaml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/MaterialDesignDemo.Shared/Examples/RadioButtonExamples/ContentPlacementExample.xaml.cs b/src/MaterialDesignDemo.Shared/Examples/RadioButtonExamples/ContentPlacementExample.xaml.cs
new file mode 100644
index 0000000000..e9a386fd5b
--- /dev/null
+++ b/src/MaterialDesignDemo.Shared/Examples/RadioButtonExamples/ContentPlacementExample.xaml.cs
@@ -0,0 +1,12 @@
+namespace MaterialDesignDemo.Shared.Examples.RadioButtonExamples;
+
+///
+/// Interaction logic for ContentPlacementExample.xaml
+///
+public partial class ContentPlacementExample : UserControl
+{
+ public ContentPlacementExample()
+ {
+ InitializeComponent();
+ }
+}
diff --git a/src/MaterialDesignThemes.Wpf/CheckBoxAssist.cs b/src/MaterialDesignThemes.Wpf/CheckBoxAssist.cs
index 529a1a293c..c9e3a53d33 100644
--- a/src/MaterialDesignThemes.Wpf/CheckBoxAssist.cs
+++ b/src/MaterialDesignThemes.Wpf/CheckBoxAssist.cs
@@ -11,4 +11,17 @@ public static readonly DependencyProperty CheckBoxSizeProperty
public static double GetCheckBoxSize(CheckBox element) => (double)element.GetValue(CheckBoxSizeProperty);
public static void SetCheckBoxSize(CheckBox element, double checkBoxSize) => element.SetValue(CheckBoxSizeProperty, checkBoxSize);
#endregion
+
+ #region AttachedProperty : ContentPlacementProperty
+ ///
+ /// Where the content is placed relative to the check box glyph.
+ ///
+ public static readonly DependencyProperty ContentPlacementProperty
+ = DependencyProperty.RegisterAttached("ContentPlacement", typeof(Dock), typeof(CheckBoxAssist), new PropertyMetadata(Dock.Right));
+
+ public static Dock GetContentPlacement(CheckBox element)
+ => (Dock)element.GetValue(ContentPlacementProperty);
+ public static void SetContentPlacement(CheckBox element, Dock value)
+ => element.SetValue(ContentPlacementProperty, value);
+ #endregion
}
diff --git a/src/MaterialDesignThemes.Wpf/RadioButtonAssist.cs b/src/MaterialDesignThemes.Wpf/RadioButtonAssist.cs
index c36cf7e677..9e426eba42 100644
--- a/src/MaterialDesignThemes.Wpf/RadioButtonAssist.cs
+++ b/src/MaterialDesignThemes.Wpf/RadioButtonAssist.cs
@@ -19,5 +19,19 @@ public static double GetRadioButtonSize(RadioButton element) =>
public static void SetRadioButtonSize(RadioButton element, double checkBoxSize) =>
element.SetValue(RadioButtonSizeProperty, checkBoxSize);
#endregion
+
+ #region AttachedProperty : ContentPlacementProperty
+ ///
+ /// Where the content is placed relative to the radio button glyph.
+ ///
+ public static readonly DependencyProperty ContentPlacementProperty
+ = DependencyProperty.RegisterAttached("ContentPlacement", typeof(Dock), typeof(RadioButtonAssist), new PropertyMetadata(Dock.Right));
+
+ public static Dock GetContentPlacement(RadioButton element)
+ => (Dock)element.GetValue(ContentPlacementProperty);
+
+ public static void SetContentPlacement(RadioButton element, Dock value)
+ => element.SetValue(ContentPlacementProperty, value);
+ #endregion
}
}
diff --git a/src/MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.CheckBox.xaml b/src/MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.CheckBox.xaml
index 2c5d2fbdc4..be67db5b09 100644
--- a/src/MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.CheckBox.xaml
+++ b/src/MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.CheckBox.xaml
@@ -97,65 +97,78 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -249,16 +262,16 @@
-
-
-
-
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.RadioButton.xaml b/src/MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.RadioButton.xaml
index 9f7e8800ef..14e5e2220e 100644
--- a/src/MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.RadioButton.xaml
+++ b/src/MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.RadioButton.xaml
@@ -69,66 +69,77 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -216,16 +227,16 @@
-
-
-
-
-
-
+
+ HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
+ VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
+ DockPanel.Dock="Left">
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/MaterialDesignThemes.Wpf.Tests/CheckBoxAssistTests.cs b/tests/MaterialDesignThemes.Wpf.Tests/CheckBoxAssistTests.cs
index cd0f875245..5f34f33ea6 100644
--- a/tests/MaterialDesignThemes.Wpf.Tests/CheckBoxAssistTests.cs
+++ b/tests/MaterialDesignThemes.Wpf.Tests/CheckBoxAssistTests.cs
@@ -16,4 +16,39 @@ public async Task TestCheckBoxSizeProperty()
CheckBoxAssist.SetCheckBoxSize(testElement, 27.1);
await Assert.That(CheckBoxAssist.GetCheckBoxSize(testElement)).IsEqualTo(27.1);
}
+
+ [Test, STAThreadExecutor]
+ public async Task TestContentPlacementProperty()
+ {
+ CheckBox testElement = new();
+
+ // Assert defaults
+ await Assert.That(CheckBoxAssist.ContentPlacementProperty.Name).IsEqualTo("ContentPlacement");
+ await Assert.That(CheckBoxAssist.GetContentPlacement(testElement)).IsEqualTo(Dock.Right);
+
+ // Assert setting works
+ CheckBoxAssist.SetContentPlacement(testElement, Dock.Top);
+ await Assert.That(CheckBoxAssist.GetContentPlacement(testElement)).IsEqualTo(Dock.Top);
+ }
+
+ [Test, STAThreadExecutor]
+ // Dont parse the theme dictionaries in parallel, as it causes race conditions in WPFs XAML reader
+ [NotInParallel("ThemeDictionaryParsing")]
+ [Arguments("MaterialDesignCheckBox", Dock.Right, Dock.Left)]
+ [Arguments("MaterialDesignCheckBox", Dock.Left, Dock.Right)]
+ [Arguments("MaterialDesignCheckBox", Dock.Top, Dock.Bottom)]
+ [Arguments("MaterialDesignCheckBox", Dock.Bottom, Dock.Top)]
+ [Arguments("MaterialDesignUserForegroundCheckBox", Dock.Right, Dock.Left)]
+ [Arguments("MaterialDesignUserForegroundCheckBox", Dock.Left, Dock.Right)]
+ [Arguments("MaterialDesignUserForegroundCheckBox", Dock.Top, Dock.Bottom)]
+ [Arguments("MaterialDesignUserForegroundCheckBox", Dock.Bottom, Dock.Top)]
+ public async Task ContentPlacement_DocksGlyphOnOppositeSide(string styleKey, Dock placement, Dock expectedGlyphDock)
+ {
+ CheckBox checkBox = new() { Content = "Label" };
+ CheckBoxAssist.SetContentPlacement(checkBox, placement);
+ checkBox.ApplyStyle(styleKey);
+
+ var glyph = (FrameworkElement)checkBox.Template.FindName("IconWrapper", checkBox);
+ await Assert.That(DockPanel.GetDock(glyph)).IsEqualTo(expectedGlyphDock);
+ }
}
diff --git a/tests/MaterialDesignThemes.Wpf.Tests/RadioButtonAssistTests.cs b/tests/MaterialDesignThemes.Wpf.Tests/RadioButtonAssistTests.cs
new file mode 100644
index 0000000000..88cd7fd775
--- /dev/null
+++ b/tests/MaterialDesignThemes.Wpf.Tests/RadioButtonAssistTests.cs
@@ -0,0 +1,38 @@
+namespace MaterialDesignThemes.Wpf.Tests;
+
+[TestExecutor]
+public class RadioButtonAssistTests
+{
+ [Test, STAThreadExecutor]
+ public async Task TestContentPlacementProperty()
+ {
+ RadioButton testElement = new();
+
+ await Assert.That(RadioButtonAssist.ContentPlacementProperty.Name).IsEqualTo("ContentPlacement");
+ await Assert.That(RadioButtonAssist.GetContentPlacement(testElement)).IsEqualTo(Dock.Right);
+
+ RadioButtonAssist.SetContentPlacement(testElement, Dock.Left);
+ await Assert.That(RadioButtonAssist.GetContentPlacement(testElement)).IsEqualTo(Dock.Left);
+ }
+
+ [Test, STAThreadExecutor]
+ // Dont parse the theme dictionaries in parallel, as it causes race conditions in WPFs XAML reader
+ [NotInParallel("ThemeDictionaryParsing")]
+ [Arguments("MaterialDesignRadioButton", Dock.Right, Dock.Left)]
+ [Arguments("MaterialDesignRadioButton", Dock.Left, Dock.Right)]
+ [Arguments("MaterialDesignRadioButton", Dock.Top, Dock.Bottom)]
+ [Arguments("MaterialDesignRadioButton", Dock.Bottom, Dock.Top)]
+ [Arguments("MaterialDesignUserForegroundRadioButton", Dock.Right, Dock.Left)]
+ [Arguments("MaterialDesignUserForegroundRadioButton", Dock.Left, Dock.Right)]
+ [Arguments("MaterialDesignUserForegroundRadioButton", Dock.Top, Dock.Bottom)]
+ [Arguments("MaterialDesignUserForegroundRadioButton", Dock.Bottom, Dock.Top)]
+ public async Task ContentPlacement_DocksGlyphOnOppositeSide(string styleKey, Dock contentPlacement, Dock expectedGlyphDock)
+ {
+ RadioButton radioButton = new() { Content = "Label" };
+ RadioButtonAssist.SetContentPlacement(radioButton, contentPlacement);
+ radioButton.ApplyStyle(styleKey);
+
+ var glyph = (FrameworkElement)radioButton.Template.FindName("IconWrapper", radioButton);
+ await Assert.That(DockPanel.GetDock(glyph)).IsEqualTo(expectedGlyphDock);
+ }
+}