我正在尝试从一个 UserControl
发送命令给另一个。第一个包含一个按钮,第二个包含一个从 Border
派生的自定义类。类(class)。
我想要当我点击Button
在 UserControl
执行Redraw method
在 CustomBorder
在 UserControl2
.
这是我到目前为止所做的。
MainWindow.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>
自定义边框类:
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 方法真正应该做什么?如果某些属性已更改,请更改边框?例如。商店里的商品卖光了?
一般来说, View 应该反射(reflect) ViewModel 的变化。这会在绑定(bind)中自动发生。 View 元素,例如按钮,可以通过命令与 ViewModel 进行通信。
因此,您的按钮将如下所示:
<Button Command={Binding ClickCommand} />
在您的 ViewModel 中,您将拥有一个
public DelegateCommand ClickCommand {get; private set;}
和
ClickCommand = new DelegateCommand(ExecuteClick);
ExecuteClick 会更新 View 模型中的一些属性,例如如果您有在线商店,请将自行车对象的 SoldOut 属性设置为 true。
如果某些属性发生更改,您的 View 将依次绑定(bind)到 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 再次绑定(bind)到一个列表,它的源绑定(bind)到诸如 ViewModel 上的 ObservableCollection 之类的东西。
所以基本上你不应该调用重绘,它应该用命令、虚拟机的变化和绑定(bind)自动重绘自己。
更新您的评论:鉴于我理解您重绘的目的,这就是我试图展示的内容。在我的示例中,产品和已售商品的红色背景将如下所示:
在您的虚拟机中:
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 背景(或边框..)
关于c# - 在 WPF 中的两个用户控件之间发送命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25032572/