将命令从MainWindowViewModel绑定到UserControl中的Slider值更改事件

时间:2019-03-03 01:59:10

标签: wpf

我的MainWindowViewModel中有一个命令,该命令在被触发时执行一个动作。我希望在MyUserControl中的滑块更改值时关闭该命令。

处理此问题的最佳方法是什么?

我当前正在将某些属性绑定到MyUserControl的依赖项属性,并且效果很好。

喜欢...

<controls:MyUserControl MySliderValue="{Binding Path=TheSliderValue, Mode=TwoWay}" />

当MyUserControl中的滑块移动时,SSliderValue将按预期正确更新。

但是,我不太确定如何将我的命令之一绑定到MyUserControl的滑块,以便在滑块移动时将其触发。

处理此问题的最佳方法是什么?

谢谢!

2 个答案:

答案 0 :(得分:1)

您可以使用System.Windows.Interactivity提供的交互性/交互性触发器来通过以下命令绑定控件的事件:

    <Slider Minimum="10" Maximum="100">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="ValueChanged">
                <i:InvokeCommandAction Command="{Binding MyCommand}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </Slider>

确保添加System.Windows.Interactivity作为参考:

WPF Add reference

您可以向每个控件添加多个EventTriggers。使用EventName-property定义要在其上调用命令的事件。

更多信息:

EventTrigger

InvokeCommandAction

Complete tutorial

答案 1 :(得分:0)

因此,听起来您想创建自定义事件,然后在视图模型中订阅这些事件。这实际上是两件事。

第一步涉及在控件中创建自定义事件,类似于您已经熟悉的ClickPreviewMouseDown等。很多信息here和{{ 3}}。您可以根据需要使用默认的RoutedEventHandlerRoutedEventArgs类,但是有可能要传递其他参数,因此请首先为其创建一个新类:

public class CustomEventArgs : RoutedEventArgs
{
    public string Arg { get; }

    public CustomEventArgs(string arg) : base(MyUserControl.CustomEvent) => (Arg) = arg;
}

然后在自定义类中为处理程序创建一个委托以接受此委托,然后创建路由事件本身:

public delegate void CustomEventHandler(object sender, CustomEventArgs args);

public static readonly RoutedEvent CustomEvent = EventManager.RegisterRoutedEvent(
    "Custom", RoutingStrategy.Bubble, typeof(CustomEventHandler), typeof(MyUserControl));

// Provide CLR accessors for the event
public event RoutedEventHandler Custom
{
    add { AddHandler(CustomEvent, value); }
    remove { RemoveHandler(CustomEvent, value); }
}

现在,您的用户控件可以随时通过执行以下操作引发此事件:

RaiseEvent(new CustomEventArgs("Hello World!"));

因此,现在当您使用自定义控件时,就可以为它添加处理程序,就像处理任何其他事件一样:

<!-- XAML -->
<controls:MyUserControl Custom="OnMyUserControl">

// Parent class's code-behind
private void OnMyUserControl(object sender, CustomEventArgs e)
{
    // do something
}

问题的第二部分基本上是如何将事件路由到视图模型中的命令处理程序。为此,您可以摆脱事件处理程序,而使用交互事件触发器:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Platform"


<controls:MyUserControl>

    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Custom">
            <cmd:EventToCommand Command="{Binding CustomCommand}" PassEventArgsToCommand="True" />
        </i:EventTrigger>
    </i:Interaction.Triggers>

</controls:MyUserControl>

然后在视图模型中为其创建处理程序:

private ICommand _CustomCommand;
public ICommand CustomCommand => this._CustomCommand ?? (this._CustomCommand = new RelayCommand<CustomEventArgs>(OnCustom));

private void OnCustom(CustomEventArgs args)
{
    // do something here
}

有道理吗?