我在样式中使用CommandBinding存在一些问题。我有以下XAML:
<Window.Resources>
<local:PolygonConverter x:Key="PolygonConverter"/>
<Style x:Key="Header" TargetType="GridViewColumnHeader">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Width="80" HorizontalContentAlignment="Center"
Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=GridViewColumnHeader, AncestorLevel=1}, Path=Tag}"
Command="{Binding ChangeSortOrder}">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource PolygonConverter}">
<Binding ElementName="P_up"/>
<Binding ElementName="P_down"/>
</MultiBinding>
</Button.CommandParameter>
</Button>
<!--<Label Width="80" HorizontalContentAlignment="Center" Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=GridViewColumnHeader, AncestorLevel=1}, Path=Tag}" />-->
<StackPanel Orientation="Vertical">
<Polygon Name="P_up" Points="0,5 10,5, 5,0" Stroke="Black" Fill="Black" Margin="3" Visibility="Hidden"/>
<Polygon Name="P_down" Points="0,0 10,0, 5,5" Stroke="Black" Fill="Black" Margin="3" Visibility="Hidden"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
<EventSetter Event="Click" Handler="Header_Click"/>
<Setter Property="Command" Value="{Binding ChangeSortOrder}"/>
<Setter Property="CommandParameter">
<Setter.Value>
<MultiBinding Converter="{StaticResource PolygonConverter}">
<Binding ElementName="P_up"/>
<Binding ElementName="P_down"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<ListView Height="300" x:Name="lv" ItemsSource="{Binding PLCs}">
<ListView.View>
<GridView>
<GridViewColumn Width="100" DisplayMemberBinding="{Binding Producer}" >
<GridViewColumnHeader Tag="Producer" Style="{StaticResource Header}"/>
</GridViewColumn>
<GridViewColumn Width="100" DisplayMemberBinding="{Binding PlcType}" >
<GridViewColumnHeader Tag="Type" Style="{StaticResource Header}"/>
</GridViewColumn>
<GridViewColumn Width="100" DisplayMemberBinding="{Binding IP}" >
<GridViewColumnHeader Tag="IP" Style="{StaticResource Header}"/>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
在我的代码中(都在同一名称空间中),我有转换器:
public class PolygonConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values.Clone();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
和 ViewModel :
class ViewModelPlcs : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = (sender, e) => { };
public ViewModelPlcs()
{
ChangeSortOrder = new RelayCommand((param) => { changeSortOrder(param); });
}
private ObservableCollection<PLC> _plcs;
public ObservableCollection<PLC> PLCs
{
get
{
if (_plcs == null)
_plcs = new ObservableCollection<PLC>();
return _plcs;
}
set
{
_plcs = value;
PropertyChanged(this, new PropertyChangedEventArgs(nameof(PLCs)));
}
}
public static void changeSortOrder(object parameter)
{
if (parameter is Array)
{
Polygon[] ps = parameter as Polygon[];
foreach (var poly in ps)
{
var visibility = poly.Visibility;
switch (visibility)
{
case Visibility.Collapsed:
case Visibility.Hidden:
visibility = Visibility.Visible;
break;
case Visibility.Visible:
visibility = Visibility.Hidden;
break;
default: break;
}
poly.Visibility = visibility;
}
}
}
private RelayCommand _changeSortOrder;
public RelayCommand ChangeSortOrder
{
get
{
return _changeSortOrder;
}
set
{
_changeSortOrder = value;
}
}
}
窗口的 DataContext 设置为ViewModel的实例。当我运行程序时,我设置了一些断点。在PolygonConverter的 Convert 中一个,在 changeSortOrder 中一个。有趣的第一件事是它在 Convert 中停止6次-好的,每个 ColumnHeader 停止3次, Button 停止3次在ColumnHeader中。但是对于 Buttons ,该值是两个多边形的数组,而ColumnHeaders的值是两个 DependencyProperty.UnsetValue 的数组(已确认通过评论按钮)。为Button命中断点的前3次。实际的窗口会显示一秒钟,并且标题会被点击。
第二个问题是,只有在我单击按钮以外的其他区域中的 Header 时,才会触发 Command 。触发时,参数为 DependencyProperty.UnsetValue 的数组。
最后,我只需要为Header或Button(最好是Header)触发命令,因为这样我就可以将其改回看起来更好的Label或TextBlock。
为什么行为是“转换值”和“命令触发”行为? 我必须更改什么才能使其正常工作(最好是对于Header)? 是否有更好的方法可以做到这一点?您可能已经注意到,我使用了 Command 和 Click 事件-在Command中,如果我对项进行了实际排序,则处理外观。在Command中同时执行这两种方法是否更好?
感谢您的帮助。