Как воспользоваться MVVM Light EventToCommand для связывания множества одинаковых событий в XAML? - PullRequest
0 голосов
/ 27 сентября 2018

Позвольте мне объяснить мои требования:

У меня есть сетка, содержащая несколько флажков, подобных этому:

<Grid>

    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>

    <CheckBox>1</CheckBox>
    <CheckBox
        Grid.Column="1">2</CheckBox>
</Grid>

Я четко знаю, как использовать mvvm light EventToCommand для привязки к команде (который определен в моей ВМ или где-либо еще).Но, как мы все знаем, у меня есть более 1 флажок.Поэтому я должен сделать это следующим образом:

    <CheckBox
        Content="1">
        <i:Interaction.Triggers>
            <i:EventTrigger
                EventName="Checked">
                <ml:EventToCommand
                    Command="{Binding SomeCommand}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </CheckBox>
    <CheckBox
        Grid.Column="1"
        Content="2">
        <i:Interaction.Triggers>
            <i:EventTrigger
                EventName="Checked">
                <ml:EventToCommand
                    Command="{Binding SomeCommand}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </CheckBox>

Если у меня есть больше флажков, мне придется снова и снова нажимать C + V, чтобы каждый флажок имел одинаковое поведение EventToCommand.Что еще более раздражает, так это то, что у нас есть еще одно событие с именем Unchecked.Обычно обратный вызов для Checked и Uncheck абсолютно одинаков.Так что я должен снова и снова C + V ..........

И, наконец, мой XAML длинный и сложный!

====================================================

Я думаю окакой-то обходной путь, подобный этому:

Я изучил исходный код события Checked, а также события Unchecked и обнаружил, что оба они были RoutedEvent с режимом Bubble, что означает, что этот перенаправленный вызов события всплывает до сетки, котораясодержит их.Поэтому я написал свой код XAML следующим образом:

<Grid>  
    <i:Interaction.Triggers>
        <i:EventTrigger
            EventName="ToggleButton.Checked">
            <ml:EventToCommand
                Command="{Binding TestCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
    ......several check boxes......
</Grid>

Но приведенные выше коды не будут работать.Ни Checked, ни Unchecked не является событием ATTACHED.

Затем я удалил «ToggleButton.», Например:

        <i:EventTrigger
            EventName="Checked">
            <ml:EventToCommand
                Command="{Binding TestCommand}" />
        </i:EventTrigger>

Все еще не работает!: (

События должны пузыриться до сетки, не так ли?

Итак, у кого-нибудь есть хорошие идеи по этому поводу? Спасибо!

Ответы [ 2 ]

0 голосов
/ 29 сентября 2018

Спасибо за ваше предложение.Это действительно удобно.Я также нашел другое решение, которое было опубликовано на этом сайте: ссылка В вышеупомянутом сообщении было упомянуто другое решение:

using System;
using System.Windows;
using System.Windows.Interactivity;

namespace NaiveMepUi.GuiCommon
{
public class RoutedEventTrigger : EventTriggerBase<DependencyObject>
{
    public RoutedEventTrigger() { }

    public RoutedEvent RoutedEvent { get; set; }

    protected override void OnAttached()
    {
        Behavior behavior = base.AssociatedObject as Behavior;
        FrameworkElement associatedElement =
            base.AssociatedObject as FrameworkElement;

        if (behavior != null)
        {
            associatedElement =
                ((IAttachedObject)behavior).AssociatedObject as FrameworkElement;
        }
        if (associatedElement == null)
        {
            throw new ArgumentException
                ("RoutedEventTrigger.AssociatedObject is not FrameworkElement.");
        }
        if (RoutedEvent != null)
        {
            associatedElement.AddHandler(
                RoutedEvent,
                new RoutedEventHandler(this.OnRoutedEvent));
        }
    }

    /// <summary>
    /// 路由事件被引发,继而引发基类的事件回调;
    /// 但是这一步会丢弃<paramref name="sender"/>。
    /// 如果事件绑定到命令,则命令只能接收到<paramref name="args"/>;
    /// 作为在 ViewModel 中定义的命令,原则上不应该 View 中定义的元素。
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="args"></param>
    void OnRoutedEvent(object sender, RoutedEventArgs args)
    {
        base.OnEvent(args);
    }

    protected override string GetEventName()
    {
        return RoutedEvent.Name;
    }
}
}

Затем я могу использовать его в XAML следующим образом:

       <Grid>     
            <i:Interaction.Triggers>
                <guicommon:RoutedEventTrigger
                    RoutedEvent="CheckBox.Checked">
                    <ml:EventToCommand
                        Command="{Binding }" />
                    <!--todo 测试一下这种设计模式是否可行-->
                </guicommon:RoutedEventTrigger>
            </i:Interaction.Triggers>
       </Grid>
0 голосов
/ 27 сентября 2018

Вы можете определить неявное Style для всех CheckBoxes в Grid:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.Resources>
        <Style TargetType="CheckBox">
            <Setter Property="Command" Value="{Binding SomeCommand}" />
        </Style>
    </Grid.Resources>

    <CheckBox>1</CheckBox>
    <CheckBox Grid.Column="1">2</CheckBox>
</Grid>

И вместо обработки событий Checked и Unchecked вы можете привязать кIsChecked свойство каждого CheckBox для свойства источника:

<CheckBox IsChecked="{Binding IsFirstChecked}">1</CheckBox>
...