WPF 专栏 header 单击命令绑定命令参数 MVVM
WPF column header click command binding with command parameter MVVM
我正在尝试自己处理 WPF DataGrid 中的排序功能。
我需要能够在单击列 header 时绑定命令,并将绑定的 属性 名称作为命令参数发送给命令。
这是我目前拥有的:
XAML:
<DataGrid Grid.Row="2" Margin="{StaticResource ControlStartPosition}"
RowStyle="{StaticResource SelectedRowNoBackgroundColor}"
CellStyle="{StaticResource SelectedCellNoBackgroundColor}"
Style="{StaticResource AlternatingRowBackgroundGridStyle}"
x:Name="MechanicsGrid"
ItemsSource="{Binding Mechanics}"
IsReadOnly="True"
GridLinesVisibility="All"
SelectionUnit="FullRow"
AutoGenerateColumns="False">
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}" BasedOn="{StaticResource MetroDataGridColumnHeader}">
<Setter Property="Controls:ControlsHelper.ContentCharacterCasing" Value="Normal"/>
<Setter Property="Command" Value="{Binding DataContext.GridSortCommand, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
<Setter Property="CommandParameter" Value="{Binding Path=Content, RelativeSource={RelativeSource Self}}"/>
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid.Columns>
<DataGridTextColumn Width="*" Header="{x:Static p:MechanicsView.GridMechanicNameColumn}" Binding="{Binding Name}" />
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Command="{Binding Path=DataContext.DeleteMechanicCommand,RelativeSource= {RelativeSource FindAncestor,AncestorType={x:Type DataGrid}}}"
CommandParameter="{Binding Path=Id}" Width="27" Height="27" Margin="10 -5 10 -5" Style="{DynamicResource MetroCircleButtonStyle}">
<Rectangle Width="11" Height="11" Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}">
<Rectangle.OpacityMask>
<VisualBrush Stretch="Fill" Visual="{DynamicResource appbar_close}" />
</Rectangle.OpacityMask>
</Rectangle>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
视图模型:
private ObservableCollection<MechanicModel> mechanics;
public ObservableCollection<MechanicModel> Mechanics
{
get
{
return mechanics;
}
set
{
Set(() => Mechanics, ref mechanics, value);
}
}
网格绑定到此 属性,在机械模型中我只有两个属性:
private int id;
public int Id
{
get
{
return id;
}
set
{
Set(() => Id, ref id, value);
}
}
private string name;
public string Name
{
get
{
return name;
}
set
{
Set(() => Name, ref name, value);
ValidateProperty(nameof(Name), value);
}
}
命令:
绑定到列header的命令是:
private RelayCommand<object> gridSortCommand;
public RelayCommand<object> GridSortCommand
{
get
{
return gridSortCommand
?? (gridSortCommand = new RelayCommand<object>(
p =>
{
},
p => true));
}
}
所以对于 p => 我目前得到列的标题,我想得到的是 属性 名称,在这种情况下至少 "Name" 作为字符串,这样我就可以构建我的排序视图中的逻辑 model.Unfortenatly 我无法将其绑定为命令参数。
如果你想在你的命令中传递参数,你需要做的就是使用MultiBinding
然后可以按如下方式使用:
<MultiBinding>
<Binding Path="Id"/>
<Binding Path="Name"/>
<Binding Path="DirectionOfSort"/>
</MultiBinding>
但是,要做到这一点,您需要稍微改变一下 xaml。
所以来自:
<Setter Property="CommandParameter" Value="{Binding Path=Content, RelativeSource={RelativeSource Self}}"/>
您需要将其更改为:
<DataGrid>
<DataGrid.ColumnHeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="CommandParameter">
<Setter.Value>
<MultiBinding Converter="{StaticResource multi}">
<Binding Path="Id"/>
<Binding Path="Name"/>
<Binding Path="{x:Static util:Enumeration.EDirection}"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</DataGrid.ColumnHeaderStyle>
</DataGrid>
你的转换器是这样的:
namespace View.Converters
{
public class MultiValueConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return values.Clone();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
并且在 xaml 中:
<converter:MultiValueConverter x:Key="multi"/>
你这样引用的:
xmlns:converter="clr-namespace:View.Converters"
你的 Util
基本上是一个在你的 xaml 中引用的枚举,如下所示:
xmlns:util="clr-namespace:Utilities;assembly=Utilities"
我正在尝试自己处理 WPF DataGrid 中的排序功能。 我需要能够在单击列 header 时绑定命令,并将绑定的 属性 名称作为命令参数发送给命令。
这是我目前拥有的:
XAML:
<DataGrid Grid.Row="2" Margin="{StaticResource ControlStartPosition}"
RowStyle="{StaticResource SelectedRowNoBackgroundColor}"
CellStyle="{StaticResource SelectedCellNoBackgroundColor}"
Style="{StaticResource AlternatingRowBackgroundGridStyle}"
x:Name="MechanicsGrid"
ItemsSource="{Binding Mechanics}"
IsReadOnly="True"
GridLinesVisibility="All"
SelectionUnit="FullRow"
AutoGenerateColumns="False">
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}" BasedOn="{StaticResource MetroDataGridColumnHeader}">
<Setter Property="Controls:ControlsHelper.ContentCharacterCasing" Value="Normal"/>
<Setter Property="Command" Value="{Binding DataContext.GridSortCommand, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
<Setter Property="CommandParameter" Value="{Binding Path=Content, RelativeSource={RelativeSource Self}}"/>
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid.Columns>
<DataGridTextColumn Width="*" Header="{x:Static p:MechanicsView.GridMechanicNameColumn}" Binding="{Binding Name}" />
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Command="{Binding Path=DataContext.DeleteMechanicCommand,RelativeSource= {RelativeSource FindAncestor,AncestorType={x:Type DataGrid}}}"
CommandParameter="{Binding Path=Id}" Width="27" Height="27" Margin="10 -5 10 -5" Style="{DynamicResource MetroCircleButtonStyle}">
<Rectangle Width="11" Height="11" Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}">
<Rectangle.OpacityMask>
<VisualBrush Stretch="Fill" Visual="{DynamicResource appbar_close}" />
</Rectangle.OpacityMask>
</Rectangle>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
视图模型:
private ObservableCollection<MechanicModel> mechanics;
public ObservableCollection<MechanicModel> Mechanics
{
get
{
return mechanics;
}
set
{
Set(() => Mechanics, ref mechanics, value);
}
}
网格绑定到此 属性,在机械模型中我只有两个属性:
private int id;
public int Id
{
get
{
return id;
}
set
{
Set(() => Id, ref id, value);
}
}
private string name;
public string Name
{
get
{
return name;
}
set
{
Set(() => Name, ref name, value);
ValidateProperty(nameof(Name), value);
}
}
命令:
绑定到列header的命令是:
private RelayCommand<object> gridSortCommand;
public RelayCommand<object> GridSortCommand
{
get
{
return gridSortCommand
?? (gridSortCommand = new RelayCommand<object>(
p =>
{
},
p => true));
}
}
所以对于 p => 我目前得到列的标题,我想得到的是 属性 名称,在这种情况下至少 "Name" 作为字符串,这样我就可以构建我的排序视图中的逻辑 model.Unfortenatly 我无法将其绑定为命令参数。
如果你想在你的命令中传递参数,你需要做的就是使用MultiBinding
然后可以按如下方式使用:
<MultiBinding>
<Binding Path="Id"/>
<Binding Path="Name"/>
<Binding Path="DirectionOfSort"/>
</MultiBinding>
但是,要做到这一点,您需要稍微改变一下 xaml。
所以来自:
<Setter Property="CommandParameter" Value="{Binding Path=Content, RelativeSource={RelativeSource Self}}"/>
您需要将其更改为:
<DataGrid>
<DataGrid.ColumnHeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="CommandParameter">
<Setter.Value>
<MultiBinding Converter="{StaticResource multi}">
<Binding Path="Id"/>
<Binding Path="Name"/>
<Binding Path="{x:Static util:Enumeration.EDirection}"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</DataGrid.ColumnHeaderStyle>
</DataGrid>
你的转换器是这样的:
namespace View.Converters
{
public class MultiValueConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return values.Clone();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
并且在 xaml 中:
<converter:MultiValueConverter x:Key="multi"/>
你这样引用的:
xmlns:converter="clr-namespace:View.Converters"
你的 Util
基本上是一个在你的 xaml 中引用的枚举,如下所示:
xmlns:util="clr-namespace:Utilities;assembly=Utilities"