Привязка к свойству Command в пользовательском элементе управления наследуемой кнопки - PullRequest
0 голосов
/ 01 февраля 2020

Я создал пользовательский элемент управления с именем 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.
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...