样式的命令绑定

时间:2018-12-17 16:19:21

标签: c# xaml datatemplate commandbinding

我在样式中使用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中同时执行这两种方法是否更好?

感谢您的帮助。

0 个答案:

没有答案