Я создал пользовательский элемент управления с именем ActionButton
, унаследованный от Button
. Я добавил пару свойств зависимостей, которые работают отлично, однако я не могу заставить работать привязку к свойству Command. Когда приложение запускается, свойство Command всегда возвращает null
.
Может кто-нибудь сказать мне, что я делаю неправильно?
Вот код, которого, я надеюсь, должно хватить.
// Custom control
public class ActionButton : Button
{
static ActionButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ActionButton), new FrameworkPropertyMetadata(typeof(ActionButton)));
}
// Some dependency properties go here
}
// In Generic.xaml
<Style TargetType="{x:Type controls:ActionButton}">
<Setter Property="Width" Value="48"/>
<Setter Property="Height" Value="48"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:ActionButton}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Border.ToolTip>
<StackPanel Margin="{DynamicResource ToolTipMargin}" MaxWidth="{DynamicResource MaxToolTipWidth}">
<TextBlock Style="{DynamicResource ToolTipHeaderStyle}" Text="{TemplateBinding ToolTipHeader}"/>
<Separator Visibility="Hidden"/>
<TextBlock Style="{DynamicResource ToolTipContentStyle}" Text="{TemplateBinding ToolTipText}"/>
</StackPanel>
</Border.ToolTip>
<Grid>
<Ellipse x:Name="BackEllipse" Stroke="{DynamicResource MahApps.Brushes.Accent}" StrokeThickness="0" Fill="{DynamicResource MahApps.Brushes.Accent}"/>
<Ellipse x:Name="FillEllipse" Stroke="{DynamicResource MahApps.Brushes.Accent}" StrokeThickness="3"/>
<TextBlock x:Name="BlockIconTextBox" Text="{TemplateBinding Icon, Converter={StaticResource FontIconConverter}}" FontSize="24" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="BackEllipse" Property="Opacity" Value="0.6"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter TargetName="BackEllipse" Property="Opacity" Value="0.0"/>
<Setter TargetName="BlockIconTextBox" Property="Opacity" Value="0.6"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="FillEllipse" Property="Opacity" Value="0.3"/>
<Setter TargetName="BlockIconTextBox" Property="Opacity" Value="0.3"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
// View base class...
public class View : UserControl
{
public View()
{
ActionButtons = new ObservableCollection<ActionButton>();
}
public static readonly DependencyProperty ActionButtonsProperty = DependencyProperty.Register(nameof(ActionButtons), typeof(ObservableCollection<ActionButton>), typeof(View));
public ObservableCollection<ActionButton> ActionButtons
{
get => (ObservableCollection<ActionButton>)GetValue(ActionButtonsProperty);
set => SetValue(ActionButtonsProperty, value);
}
}
// Markup in a view...
<local:View
x:Class="Vesuvius.TeleCalc.Windows.Views.SettingsView"
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:Vesuvius.TeleCalc.Windows.Views"
xmlns:viewModels="clr-namespace:Vesuvius.TeleCalc.Windows.ViewModels"
xmlns:controls="clr-namespace:Vesuvius.TeleCalc.Windows.Controls"
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
mc:Ignorable="d" d:DesignHeight="800" d:DesignWidth="1024"
Title="Settings"
>
<local:View.DataContext>
<viewModels:SettingsViewModel />
</local:View.DataContext>
<local:View.ActionButtons >
<!-- This is where things start to go wrong (I think) -->
<controls:ActionButton Icon="Color" ToolTipHeader="Reset theme" ToolTipText="Reset theme to default values." Command="{Binding ResetThemeCommand}"/>
</local:View.ActionButtons>
<!-- I have removed the rest for brevity -->
// In SettingsViewModel...
public SettingsViewModel()
{
ResetThemeCommand = CommandFactory.Create(ResetTheme);
}
public ICommand ResetThemeCommand { get; }
private void ResetTheme(object parameter)
{
// Do stuff here
}
// The issue...
public partial class SettingsView
{
public SettingsView()
{
InitializeComponent();
// The Command of SettingsViewModel.ResetThemeCommand is always null, so I have to resort to this nasty hack...
ActionButtons[0].Command = ((SettingsViewModel)DataContext).ResetThemeCommand;
// It's also worth noting, that the dependency properties ToolTipHeader and ToolTipText of the ResetThemeCommand are working properly.
}
}