Связывание команд в стиле - PullRequest
       30

Связывание команд в стиле

0 голосов
/ 17 декабря 2018

У меня есть некоторые проблемы с CommandBinding в Style .У меня есть следующий 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>

В моем коде (все в одном и том же пространстве имен) у меня есть Converter :

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 и один в changeSortOrder .Первое, что интересно, это то, что он останавливается 6 раз в Convert - ОК, 3 раза для каждого ColumnHeader и 3 раза для Button в ColumnHeader,Но для Buttons значение представляет собой массив из двух Polygons , тогда как значение для ColumnHeaders представляет собой массив из двух DependencyProperty.UnsetValue (Подтверждено комментированиемКнопки).Первые 3 раза точка останова попадает на кнопки.Фактическое окно появляется на долю секунды, и оно попадает в заголовки.

Вторая проблема заключается в том, что Command срабатывает только при нажатии на Заголовок * 1039.* в разделе, отличном от Buttons .Когда он запускается, параметром является Массив DependencyProperty.UnsetValue .

В конце мне понадобится только команда для запуска либо для заголовка, либо для кнопки, предпочтительно заголовка, потому чтотогда я могу изменить его обратно на Label или TextBlock, который выглядит лучше.

Почему такое поведение, как и для Convert-значений и запуска команды?Что я должен изменить, чтобы заставить его работать должным образом (предпочтительно для Заголовка)?Есть ли лучший способ сделать это за все?Возможно, вы заметили, что я использовал событие Command и событие Click - в команде я обрабатываю внешний вид, если я выполняю фактическую сортировку элементов.Лучше практиковать это в Команде?

Спасибо за вашу помощь.

...