问题:
在WPF中 创建了资源字典来写自定义控件 涉及到Button,CheckBox等一系列带Command属性的操作时,需要将命令绑定到我们的代码中,这时你会想到查找器,DataContext等为按钮设置绑定,特别是在ItemsControl等拥有DataTemplate等多重绑定的,最为烦人
解决:
其实很简单,自定义控件可以直接绑定到代码中,只需要在代码中设置为Static即可,代码如下:
资源字典代码:
<Style TargetType="{x:Type local:SideMenu}">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:SideMenu}">
<Border Width="{TemplateBinding Width}" Background="#393D49">
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
<ItemsControl Padding="0" Background="Transparent" BorderThickness="0" ItemTemplateSelector="{DynamicResource MenuItemSelector}" ItemsSource="{TemplateBinding ItemsSource}">
<ItemsControl.Resources>
<local:MenuItemDataTemplateSelector x:Key="MenuItemSelector" />
<DataTemplate x:Key="MenuItemsDataTemplate">
<local:NavExpander Padding="10,0" Background="#282B33" Header="{Binding MenuName}" HeaderBackground="#393D49" IsExpanded="{Binding IsSelected}">
<ItemsControl ItemTemplateSelector="{DynamicResource MenuItemSelector}" ItemsSource="{Binding Children}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</local:NavExpander>
</DataTemplate>
<DataTemplate x:Key="MenuItemDataTemplate">
<RadioButton Height="40" Padding="20,0" Content="{Binding MenuName}" Command="{x:Static local:SideMenu.CheckCommand}"
x:Name="menuContent" FocusVisualStyle="{x:Null}" Foreground="White" GroupName="Item" IsChecked="{Binding IsSelected,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" CommandParameter="{Binding}" >
<RadioButton.Template>
<ControlTemplate TargetType="RadioButton">
<Grid>
<Border x:Name="bg" Background="Transparent" />
<Grid x:Name="line" Width="5" HorizontalAlignment="Left" Background="#50a0ff" Opacity="0" />
<ContentPresenter x:Name="dataContent" Margin="{TemplateBinding Padding}" HorizontalAlignment="Left" VerticalAlignment="Center" IsHitTestVisible="True" Opacity="0.7" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter TargetName="bg" Property="Background" Value="#242424" />
<Setter TargetName="dataContent" Property="Opacity" Value="1" />
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="line"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="line"
Storyboard.TargetProperty="Opacity"
To="0"
Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="bg" Property="Background" Value="#4c4c4c" />
<Setter TargetName="dataContent" Property="Opacity" Value="1" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</RadioButton.Template>
</RadioButton>
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
留意Command="{x:Static local:SideMenu.CheckCommand}"这一句
逻辑代码:
public class SideMenu : Control
{
public object ItemsSource
{
get { return (object)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
// Using a DependencyProperty as the backing store for ItemsSource. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(object), typeof(SideMenu), new PropertyMetadata(default(object)));
public object SelectedItem
{
get { return (object)GetValue(SelectedItemProperty); }
set { SetValue(SelectedItemProperty, value); }
}
// Using a DependencyProperty as the backing store for SelectedItem. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register("SelectedItem", typeof(object), typeof(SideMenu), new PropertyMetadata(default(object)));
public static DelegateCommand<object> CheckCommand { get; set; }
public event SelectionChangedEventHandler SelectionChanged;
public SideMenu()
{
CheckCommand = new DelegateCommand<object>(CheckCommandExecute);
}
private void CheckCommandExecute(object obj)
{
SelectedItem = obj;
SelectionChanged?.Invoke(this, null);
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
}
}
注意public static DelegateCommand CheckCommand { get; set; },要用Static修饰
记录一下!!!