问题描述
我尝试构建自定义ListBoxItem,但是我很难将Command绑定到我的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,etc...
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register(nameof(Text),typeof(string),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,etc...
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register(nameof(Command),typeof(ICommand),new PropertyMetadata(default(ICommand)));
}
在我的MainWindow中,我尝试将Command绑定到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>
有人可以告诉我我做错了什么吗?我想了解如何构建自己的控件。
解决方法
TemplateBinding
只能在ControlTemplate
中使用。因此,要解决此问题,请在您的控制模板中更改以下行:
<MouseBinding Gesture="LeftClick" Command="{TemplateBinding Command}"/>
对此:
<MouseBinding Gesture="LeftClick" Command="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=Command}"/>