在WPF应用中使用MVVM/MVVMLight时如何与UI元素进行交互 [英] How to interact with UI elements when using MVVM/MVVMLight in a WPF app

查看:579
本文介绍了在WPF应用中使用MVVM/MVVMLight时如何与UI元素进行交互的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基于下面的代码,我希望能够在单击Button 1时更改Button 2的背景颜色.

Based on my code below, I want to be able to change the background color of a Button 2 when Button 1 is clicked.

    <Grid>
        <Button x:Name="Button1" 
                Content="Button 1" 
                Command="{Binding Button1Command}"/>

        <Button x:Name="Button2" 
                Content="Button 2"/>
    </Grid>

ViewModel文件

public class MyViewModel : ViewModelBase
{
    public ICommand Button1Command{get;private set;}

    public MyViewModel(){
        Button1Command = new RelayCommand(() => button1_Click());
    }

    private void button1_Click()
    {
        Console.WriteLine("Button 1 clicked");

        // how can I change the background color of Button 2 here
        this.Dispatcher.Invoke(() => {
           Button2.Background = Brushes.Red;
        });
    }
}

推荐答案

除了pm_2提到的内容外,您还可以利用MVVMLight的Messenger类. VM可以发送View接收到的消息以更改背景.

In addition to what pm_2 mentioned, you could take advantage of MVVMLight's Messenger class. The VM can send a message that is received by the View to change the background.

public class ChangeBackgroundMessage
{
    public Brush TheColor { get; set; } 
} 

然后在您的VM中:

Button1Command = new RelayCommand(() => ExecuteButtonCommand());

....

private void ExecuteButtonCommand()
{
    Messenger.Default.Send<ChangeBackgroundMessage>(new ChangeBackgroundMessage { TheColor = Brushes.Red } );
} 

并在您的视图中:

public partial class MyView : UserControl
{
    public MyView()
    {
         InitializeComponent();
         Messenger.Default.Register<ChangeBackgroundMessage>(this, m => ReceiveChangeBackgroundMessage(m);
    } 

    private void ReceiveChangeBackgroundMessage(ChangeBackgroundMessage m)
    {
          // If you need to ensure this executes only on UI thread, use the
          // DispatcherHelper class

          DispatcherHelper.CheckBeginInvokeOnUI(() => button2.Background = m.TheColor);
    }

}

另一种替代方法是让View向其ViewModel注册视图服务".例如:

Yet another alternative would be to have a "view service" that the View registers with it's ViewModel. For example:

public interface IMySpecificViewService
{ 
    void ChangeButtonColor(Brush color);
} 

在VM中:

public IMySpecificViewService ViewService { get; set; } 

和在视图中

public partial class MyView : UserControl, IMySpecificViewService
...
public MyView()
{ 
    var vm = (MyViewModel)this.DataContext;
    vm.ViewService = (IMySpecificViewService)this;
} 

public void ChangeButtonColor(Brush color)
{
    Button2.Background = color;
}  

可以在VM的命令处理程序中调用:

which can be called in your VM's command handler:

private void ExecuteButtonCommand()
{
    ViewService?.ChangeButtonColor(Brushes.Red);
} 

当我无法直接绑定到VM中的属性时,我发现我使用了这些方法(或者我不想在VM中渗出任何View特定的东西),并且我需要更精细的控制来操纵控件.

I find I use these approaches when I can't directly bind to a property in the VM, (or I don't want to bleed any View specific stuff in the VM) and I need more fine grained control over manipulating the controls.

这篇关于在WPF应用中使用MVVM/MVVMLight时如何与UI元素进行交互的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆