在WPF中的两个用户控件之间发送命令
本文关键字:控件 用户 之间 命令 两个 WPF | 更新日期: 2023-09-27 18:15:28
我正试图将命令从一个UserControl
发送到另一个。第一个包含一个按钮,第二个包含从Border
类派生的自定义类。
我希望在单击UserControl
中的Button
时执行UserControl2
中CustomBorder
中的Redraw method
。
以下是我迄今为止所做的工作。
主窗口.xaml:
<Window x:Class="SendCommands.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sendCommands="clr-namespace:SendCommands"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<sendCommands:ViewModel/>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<sendCommands:UserControl1 Grid.Row="0"/>
<sendCommands:UserControl2 Grid.Row="1"/>
</Grid>
</Window>
用户控制1:
<UserControl x:Class="SendCommands.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Button Content="Redraw"
Width="200"
Height="30"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</UserControl>
用户控制2:
<UserControl x:Class="SendCommands.UserControl2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sendCommands="clr-namespace:SendCommands">
<Grid>
<sendCommands:CustomBorder Background="Black">
</sendCommands:CustomBorder>
</Grid>
</UserControl>
CustomBorder类:
using System.Windows;
using System.Windows.Controls;
namespace SendCommands
{
public class CustomBorder : Border
{
public void Redraw()
{
// Operations to redraw some elements inside the CustomBorder
MessageBox.Show("We did it!");
}
}
}
ViewModel.cs:
namespace SendCommands
{
class ViewModel
{
}
}
请有人帮我一劳永逸地学会这一点。我是MVVM
概念的新手,我读了很多书,但没有结果。我真的需要一个实用的解决方案来正确理解这些概念。
您的Redraw方法真正应该做什么?如果某些属性已更改,是否更改边框?例如,商店里的一件商品已经卖完了?
一般情况下,视图应反映ViewModel中的更改。绑定会自动发生这种情况。视图元素(如按钮(可以通过命令与ViewModel通信。
因此,你的按钮看起来像这样:
<Button Command={Binding ClickCommand} />
在你的ViewModel中,你会有一个
public DelegateCommand ClickCommand {get; private set;}
和
ClickCommand = new DelegateCommand(ExecuteClick);
ExecuteClick会更新视图模型中的一些属性,例如,如果您有一个在线商店,请将bike对象的SoldOut属性设置为true。
您的视图将绑定到Bike的属性,并在某些属性更改时更改其外观。像文本这样的更改将自行发生,使用转换器可以实现更复杂的更改(例如,在SoldOut中将bckaground更改为红色是真的(:
<Resources>
<SoldOutToBckgrConverter x:Key="soldOutToBckgrConverter" />
</Resources>
<Label Content={Binding Path=SelectedItem.Model} Background={Binding Path=SelectedItem.SoldOut, Converter={StaticResource soldOutToBckgrConverter}} />
SoldOutToBckgrConverter实现IValueConverter并将True转换为Red。
注意:SelectedItem再次绑定到一个列表,该列表的源绑定到ViewModel上的ObservableCollection之类的东西。
所以,基本上你不应该调用redraw,它应该通过命令、VM中的更改和绑定自动重新绘制自己。
更新你的评论:这就是我试图展示的,因为我理解你重画权的目的。在我的例子中,产品和已售出商品的红色背景看起来像这样:
在您的虚拟机中:
public ObservableCollection<MyProduct> Products {get;set;}
private MyProduct selectedProduct;
public MyProduct SelectedProduct
{
get {return selectedProduct;}
set {
if (selectedProduct != value) {
selectedProducat = value;
RaisePropertyChanged(()=>SelectedProduct;
}
}
}
MyProduct具有Model属性(真实世界的产品模型,即品牌(和SoldOut。
在您看来:
<ListBox SelectedItem="{Binding SelectedProduct, Mode=TwoWay}" ItemsSource="{Binding Products}" >
<ListBox.ItemTemplate>
<Label Content={Binding Path=SelectedItem.Model} Background={Binding Path=SelectedItem.SoldOut, Converter={StaticResource soldOutToBckgrConverter}} />
</ListBox.ItemTemplate>
</ListBox>
现在,当您单击按钮时,VM将更改SelectedProduct和Binding cahnges背景(或边界..(
您可以使用Expression Blend提供的"CallMethodAction"行为。将System.Windows.Interactivity.dll添加到项目中,就可以将该方法绑定到事件。在您的情况下,"ReDraw"方法必须绑定到"Click"事件。有关此行为的详细信息。
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<sendCommands:UserControl1 Grid.Row="0">
<i:Interaction.Triggers>
<i:EventTrigger EventName="RefreshButtonClick">
<ei:CallMethodAction MethodName="RedrawCustomBorder"
TargetObject="{Binding ElementName=customBorder}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</sendCommands:UserControl1>
<sendCommands:UserControl2 Grid.Row="1" x:Name="customBorder"/>
</Grid>