如何通过WPF中的命令调用自定义控件的方法

时间:2017-03-17 17:06:25

标签: wpf mvvm

我正在使用自定义控件向用户显示3D渲染数据。该控件具有ResetView()方法,该方法将控件的状态返回到其默认值。我有一个视图模型,它是窗口的数据上下文,那么当在同一个视图中单击一个按钮并维护MVVM结构时,如何调用控件的ResetView方法?

1 个答案:

答案 0 :(得分:1)

我通常使用的一种可行方法:

在视图模型中创建IObservable类型的属性。您可以 使用来自Reactive Extensions(RX)的Subject作为实际 实现。

public class ViewModel
{
    private Subject<Unit> _resetRequest = new Subject<Unit>();

    public IObservable<Unit> ResetRequest
    {
        get { return _resetRequest; }
    }
}

为控件创建行为。行为必须 被绑定到您的财产并订阅观察。打电话给你 从订阅OnNext处理程序控制ResetView()方法。

public class ResetViewBehavior : Behavior<YourControl>
{
    private IDisposable _subscription;

    public static readonly DependencyProperty RequestProperty = DependencyProperty.Register("Request", typeof(IObservable<Unit>), typeof(ResetViewBehavior), new PropertyMetadata(null, OnRequestChanged));

    public IObservable<Unit> Request
    {
        get { return (IObservable<Unit>)GetValue(RequestProperty); }
        set { SetValue(RequestProperty, value); }
    }

    private static void OnRequestChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
         ((ResetViewBehavior)d).Resubscribe();
    }

    private void Resubscribe()
    {
        _subscription?.Dispose();
        _subscription = Request?.Subscribe(_ => AssociatedObject.ResetView());
    }

    protected override void OnAttached()
    {
        Resubscribe();
    }

    protected override void OnDetaching()
    {
        _subscription?.Dispose();
    }

}

在XAML中:

   <Window>
        <YourControl>
            <i:Interaction.Behaviors>
                <b:ResetViewBehavior Request="{Binding ResetRequest}" />
            </i:Interaction.Behaviors>
        </YourControl>
    </Window>

如果要重置视图,请从视图模型中调用主题的OnNext方法。

public class ViewModel
{
    private Subject<Unit> _resetRequest = new Subject<Unit>();

    public IObservable<Unit> ResetRequest
    {
        get { return _resetRequest; }
    }

    private void ResetView()
    {
        _resetRequest.OnNext(new Unit());
    }
}

使用这种方法,你没有代码,我总是试图在MVVM中避免使用。相反,您将逻辑包含在可重用行为中。

如果使用其他类而不是Unit作为IObservable参数,也可以将一些数据传递给控件的方法。