-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Incorporate dialog content without having to code the buttons. Suppor…
…t UserControl and IDialog
- Loading branch information
Showing
14 changed files
with
507 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<UserControl x:Class="wpf_material_dialogs.ButtonTemplateControl" | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||
xmlns:local="clr-namespace:wpf_material_dialogs" | ||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" | ||
mc:Ignorable="d" | ||
d:DesignHeight="450" d:DesignWidth="800"> | ||
<ContentControl Margin="3 10 3 5" | ||
Height="33" | ||
VerticalContentAlignment="Bottom" | ||
HorizontalAlignment="{Binding ButtonAlignment, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" | ||
Content="{Binding SelectedButtons, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" materialDesign:ThemeAssist.Theme="Inherit" /> | ||
</UserControl> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
using System.Windows; | ||
using System.Windows.Controls; | ||
using wpf_material_dialogs.Interfaces; | ||
|
||
namespace wpf_material_dialogs | ||
{ | ||
/// <inheritdoc cref="UserControl" /> | ||
/// <summary> | ||
/// Interaction logic for ButtonTemplateControl.xaml | ||
/// </summary> | ||
public partial class ButtonTemplateControl : UserControl | ||
{ | ||
/// <summary> | ||
/// The button alignment property | ||
/// </summary> | ||
public static readonly DependencyProperty ButtonAlignmentProperty = DependencyProperty.Register( | ||
nameof(ButtonAlignment), typeof(HorizontalAlignment), typeof(ButtonTemplateControl), new PropertyMetadata(HorizontalAlignment.Right)); | ||
|
||
public static readonly DependencyProperty SelectedButtonsProperty = DependencyProperty.Register( | ||
nameof(SelectedButtons), typeof(IButtons), typeof(ButtonTemplateControl), new PropertyMetadata(default(IButtons))); | ||
|
||
public IButtons SelectedButtons | ||
{ | ||
get => (IButtons) GetValue(SelectedButtonsProperty); | ||
set => SetValue(SelectedButtonsProperty, value); | ||
} | ||
/// <summary> | ||
/// Gets or sets the button alignment. | ||
/// </summary> | ||
/// <value>The button alignment.</value> | ||
public HorizontalAlignment ButtonAlignment | ||
{ | ||
get => (HorizontalAlignment) GetValue(ButtonAlignmentProperty); | ||
set => SetValue(ButtonAlignmentProperty, value); | ||
} | ||
|
||
public ButtonTemplateControl() | ||
{ | ||
InitializeComponent(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<UserControl x:Class="wpf_material_dialogs.Dialogs.ContentDialog" | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" | ||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||
xmlns:wpfMaterialDialogs="clr-namespace:wpf_material_dialogs" | ||
mc:Ignorable="d" | ||
Height="Auto" Width="500" | ||
d:DesignHeight="450" d:DesignWidth="500"> | ||
<Grid Margin="5"> | ||
<Grid.RowDefinitions> | ||
<RowDefinition Height="*" /> | ||
<RowDefinition Height="Auto" /> | ||
</Grid.RowDefinitions> | ||
<Grid.ColumnDefinitions> | ||
<ColumnDefinition Width="*" /> | ||
</Grid.ColumnDefinitions> | ||
<StackPanel Grid.Row="0"> | ||
<ContentControl Content="{Binding ContentControl, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" /> | ||
</StackPanel> | ||
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Bottom" Margin="5" HorizontalAlignment="Right"> | ||
<wpfMaterialDialogs:ButtonTemplateControl | ||
Visibility="{Binding ShowButtons, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Converter={StaticResource BooleanToVisibilityConverter}}" | ||
ButtonAlignment="{Binding ButtonAlignment, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" | ||
SelectedButtons="{Binding SelectedButtons, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" materialDesign:ThemeAssist.Theme="Inherit" | ||
DataContext="{Binding}" | ||
/> | ||
</StackPanel> | ||
</Grid> | ||
</UserControl> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.ComponentModel; | ||
using System.Linq; | ||
using System.Reflection; | ||
using System.Runtime.CompilerServices; | ||
using System.Windows; | ||
using System.Windows.Controls; | ||
using wpf_material_dialogs.Enums; | ||
using wpf_material_dialogs.Interfaces; | ||
|
||
namespace wpf_material_dialogs.Dialogs | ||
{ | ||
/// <summary> | ||
/// Interaction logic for ContentDialog.xaml | ||
/// </summary> | ||
/// <inheritdoc cref="System.Windows.Controls.UserControl" /> | ||
public partial class ContentDialog : UserControl, INotifyPropertyChanged | ||
{ | ||
#region Events | ||
|
||
/// <inheritdoc /> | ||
/// <summary> | ||
/// Occurs when [property changed]. | ||
/// </summary> | ||
public event PropertyChangedEventHandler PropertyChanged; | ||
|
||
#endregion | ||
|
||
#region Fields | ||
|
||
/// <summary> | ||
/// The content control property | ||
/// </summary> | ||
public static readonly DependencyProperty ContentControlProperty = DependencyProperty.Register( | ||
nameof(ContentControl), typeof(object), typeof(ContentDialog), new FrameworkPropertyMetadata( | ||
default, FrameworkPropertyMetadataOptions.AffectsParentArrange | | ||
FrameworkPropertyMetadataOptions.AffectsParentMeasure | | ||
FrameworkPropertyMetadataOptions.AffectsRender | | ||
FrameworkPropertyMetadataOptions.AffectsMeasure, Refresh)); | ||
|
||
/// <summary> | ||
/// The content control property | ||
/// </summary> | ||
public static readonly DependencyProperty DialogButtonsProperty = DependencyProperty.Register( | ||
nameof(DialogButtons), typeof(DialogButton), typeof(ContentDialog), new FrameworkPropertyMetadata( | ||
DialogButton.OkButtons, FrameworkPropertyMetadataOptions.AffectsParentArrange | | ||
FrameworkPropertyMetadataOptions.AffectsParentMeasure | | ||
FrameworkPropertyMetadataOptions.AffectsRender | | ||
FrameworkPropertyMetadataOptions.AffectsMeasure, Refresh)); | ||
|
||
/// <summary> | ||
/// The button alignment property | ||
/// </summary> | ||
public static readonly DependencyProperty ButtonAlignmentProperty = DependencyProperty.Register( | ||
nameof(ButtonAlignment), typeof(HorizontalAlignment), typeof(ContentDialog), new PropertyMetadata(HorizontalAlignment.Right, Refresh)); | ||
|
||
/// <summary> | ||
/// The buttons property | ||
/// </summary> | ||
public static readonly DependencyProperty ButtonsProperty = DependencyProperty.Register( | ||
nameof(Buttons), typeof(IButtons), typeof(ContentDialog), new PropertyMetadata(default(IButtons), Refresh)); | ||
|
||
/// <summary> | ||
/// The show buttons property | ||
/// </summary> | ||
public static readonly DependencyProperty ShowButtonsProperty = DependencyProperty.Register( | ||
nameof(ShowButtons), typeof(bool), typeof(ContentDialog), new PropertyMetadata(true, Refresh)); | ||
|
||
private readonly object buttonLock = new(); | ||
private readonly List<Type> buttonTypes = new(); | ||
|
||
#endregion | ||
|
||
#region Properties | ||
|
||
/// <summary> | ||
/// Gets or sets a value indicating whether [show buttons]. | ||
/// </summary> | ||
/// <value><c>true</c> if [show buttons]; otherwise, <c>false</c>.</value> | ||
public bool ShowButtons | ||
{ | ||
get => (bool) GetValue(ShowButtonsProperty); | ||
set => SetValue(ShowButtonsProperty, value); | ||
} | ||
|
||
/// <summary> | ||
/// Gets or sets the buttons. | ||
/// </summary> | ||
/// <value>The buttons.</value> | ||
public IButtons Buttons | ||
{ | ||
get => (IButtons) GetValue(ButtonsProperty); | ||
set => SetValue(ButtonsProperty, value); | ||
} | ||
|
||
/// <summary> | ||
/// Gets or sets the button alignment. | ||
/// </summary> | ||
/// <value>The button alignment.</value> | ||
public HorizontalAlignment ButtonAlignment | ||
{ | ||
get => (HorizontalAlignment) GetValue(ButtonAlignmentProperty); | ||
set => SetValue(ButtonAlignmentProperty, value); | ||
} | ||
|
||
/// <summary> | ||
/// Gets the selected buttons based on the <see cref="DialogButtons" /> selection. | ||
/// </summary> | ||
/// <value><see cref="IButtons" />.</value> | ||
public IButtons SelectedButtons => ShowButtons | ||
? DialogButtons == DialogButton.Custom | ||
? Buttons | ||
: GetButtons(DialogButtons) | ||
: null; | ||
|
||
/// <summary> | ||
/// Gets or sets the content control. | ||
/// </summary> | ||
/// <value>The content control.</value> | ||
public object ContentControl | ||
{ | ||
get => GetValue(ContentControlProperty); | ||
set => SetValue(ContentControlProperty, value); | ||
} | ||
|
||
/// <summary> | ||
/// Gets or sets the dialog buttons. | ||
/// </summary> | ||
/// <value>The dialog buttons.</value> | ||
public DialogButton DialogButtons | ||
{ | ||
get => (DialogButton) GetValue(DialogButtonsProperty); | ||
set | ||
{ | ||
SetValue(DialogButtonsProperty, value); | ||
NotifyOfPropertyChanged(nameof(SelectedButtons)); | ||
} | ||
} | ||
|
||
#endregion | ||
|
||
/// <inheritdoc /> | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="T:wpf_material_dialogs.Dialogs.ContentDialog" /> class. | ||
/// </summary> | ||
public ContentDialog() => InitializeComponent(); | ||
|
||
/// <inheritdoc /> | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="T:wpf_material_dialogs.Dialogs.ContentDialog" /> class. | ||
/// </summary> | ||
/// <param name="contentControl">The content control.</param> | ||
public ContentDialog(UserControl contentControl) : this() => ContentControl = contentControl; | ||
|
||
/// <inheritdoc /> | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="T:wpf_material_dialogs.Dialogs.ContentDialog" /> class. | ||
/// </summary> | ||
/// <param name="contentControl">The content control.</param> | ||
public ContentDialog(IDialog contentControl) : this() => ContentControl = contentControl; | ||
|
||
/// <summary> | ||
/// Gets the buttons. | ||
/// </summary> | ||
/// <param name="button">The button enum to convert to an IButton.</param> | ||
/// <returns>IButtons.</returns> | ||
/// <exception cref="System.ArgumentOutOfRangeException">button</exception> | ||
/// <exception cref="T:System.ArgumentOutOfRangeException">button</exception> | ||
/// <exception cref="T:System.ArgumentOutOfRangeException">button</exception> | ||
/// <exception cref="T:System.ArgumentOutOfRangeException">button</exception> | ||
public IButtons GetButtons(DialogButton button) | ||
{ | ||
// ReSharper disable once PossibleNullReferenceException | ||
lock (buttonLock) | ||
{ | ||
var assembly = Assembly.GetExecutingAssembly(); | ||
|
||
if (!buttonTypes?.Any() ?? false) | ||
{ | ||
buttonTypes.AddRange(assembly | ||
.GetTypes() | ||
.Where(mytype => mytype.GetInterfaces().Contains(typeof(IButtons)))); | ||
} | ||
|
||
var selectedButtonType = | ||
buttonTypes?.First(mytype => button.ToString().Equals(mytype?.Name, StringComparison.CurrentCultureIgnoreCase)); | ||
|
||
return selectedButtonType?.FullName != null | ||
? assembly.CreateInstance(selectedButtonType.FullName) as IButtons | ||
: throw new ArgumentOutOfRangeException(nameof(button)); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Notifies the of property changed. | ||
/// </summary> | ||
/// <param name="propertyName">Name of the property.</param> | ||
/// <inheritdoc cref="INotifyPropertyChanged" /> | ||
public void NotifyOfPropertyChanged([CallerMemberName] string propertyName = "") => | ||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); | ||
|
||
/// <summary> | ||
/// Refreshes this instance. | ||
/// </summary> | ||
internal void Refresh() => NotifyOfPropertyChanged(nameof(SelectedButtons)); | ||
|
||
private static void Refresh(DependencyObject o, DependencyPropertyChangedEventArgs _) | ||
{ | ||
if (o is ContentDialog d) | ||
{ | ||
d.Refresh(); | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.