【问题标题】:Custom ListboxItem with Template Command Binding带有模板命令绑定的自定义 ListboxItem
【发布时间】:2020-09-26 16:28:41
【问题描述】:

我尝试构建一个自定义 ListboxItem,但我很难将命令绑定到我的 TemplateControl。

<Style x:Key="{x:Type controls:NavigationRailItem}" TargetType="{x:Type controls:NavigationRailItem}">
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type controls:NavigationRailItem}" >
                <StackPanel Orientation="Vertical" >
                    <StackPanel.InputBindings>
                        <MouseBinding Gesture="LeftClick" Command="{TemplateBinding Command}"/>
                    </StackPanel.InputBindings>
                    <materialDesign:PackIcon Kind="{TemplateBinding IconKind}"  HorizontalAlignment="Stretch" Width="25" Height="25" VerticalAlignment="Stretch"/>
                    <TextBlock Text="{TemplateBinding Text}" FontSize="11" HorizontalAlignment="Center"/>
                    <ContentPresenter/>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
public class NavigationRailItem : ListBoxItem
{
    static NavigationRailItem()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(NavigationRailItem), new FrameworkPropertyMetadata(typeof(NavigationRailItem)));
    }

    public PackIconKind IconKind
    {
        get { return (PackIconKind)GetValue(IconKindProperty); }
        set { SetValue(IconKindProperty, value); }
    }

    // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IconKindProperty =
        DependencyProperty.Register(nameof(IconKind), typeof(PackIconKind), typeof(NavigationRailItem), new PropertyMetadata(default(PackIconKind)));

    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register(nameof(Text), typeof(string), typeof(NavigationRailItem), new PropertyMetadata(""));

    public ICommand Command
    {
        get { return (ICommand)GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Command.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty CommandProperty =
        DependencyProperty.Register(nameof(Command), typeof(ICommand), typeof(NavigationRailItem), 
            new PropertyMetadata(default(ICommand)));
}

在我的 MainWindow 中,我尝试将命令绑定到我的 ViewModel。如果我尝试直接绑定我的 DependencyProperty,我不会得到 Click 事件。 如果我再次使用 InputBinding 在 MainWindow 中绑定它,我会得到它。最后一个测试是直接使用 ListboxItem 的原生实现。

<ListBox Grid.Column="1" HorizontalAlignment="Center">
    <Controls1:NavigationRailItem IconKind="Car" Text="Test1" Command="{Binding TestCommand}"/>
    <Separator Height="10"/>
    <Controls1:NavigationRailItem IconKind="XboxLive" Text="Test2" >
        <Controls1:NavigationRailItem.InputBindings>
            <MouseBinding Gesture="LeftClick" Command="{Binding TestCommand}"/>
        </Controls1:NavigationRailItem.InputBindings>
    </Controls1:NavigationRailItem>
    <ListBoxItem >
        <StackPanel Orientation="Vertical" >
            <StackPanel.InputBindings>
                <MouseBinding Gesture="LeftClick" Command="{Binding TestCommand}"/>
            </StackPanel.InputBindings>
            <materialDesign:PackIcon Kind="Apple"  HorizontalAlignment="Stretch" Width="25" Height="25" VerticalAlignment="Stretch"/>
            <TextBlock Text="Test3" FontSize="11" HorizontalAlignment="Center"/>
        </StackPanel>
    </ListBoxItem>
</ListBox>

谁能告诉我我做错了什么?我想了解如何构建自己的控件。

【问题讨论】:

    标签: c# wpf xaml custom-controls controltemplate


    【解决方案1】:

    TemplateBinding 只能在ControlTemplate 内使用。所以要解决这个问题,在你的控制模板中改变这一行:

    <MouseBinding Gesture="LeftClick" Command="{TemplateBinding Command}"/>
    

    到这里:

    <MouseBinding Gesture="LeftClick" Command="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Command}"/>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-29
      • 1970-01-01
      相关资源
      最近更新 更多