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>
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;
});
}
}
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; }
}
And then in your VM:
Button1Command = new RelayCommand(() => ExecuteButtonCommand());
....
private void ExecuteButtonCommand()
{
Messenger.Default.Send<ChangeBackgroundMessage>(new ChangeBackgroundMessage { TheColor = Brushes.Red } );
}
and in your View:
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);
}
}
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);
}
In VM:
public IMySpecificViewService ViewService { get; set; }
and in View
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;
}
which can be called in your VM's command handler:
private void ExecuteButtonCommand()
{
ViewService?.ChangeButtonColor(Brushes.Red);
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With