我试图将命令从一个UserControl
发送到另一个Border
。第一个包含一个按钮,第二个包含一个派生自Button
类的自定义类。
我想点击UserControl
中的Redraw method
来执行CustomBorder
中UserControl2
中的<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>
。
这是我到目前为止所做的。
MainWindow.xaml:
<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>
的UserControl1:
<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>
UserControl2:
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!");
}
}
}
CustomBorder类:
namespace SendCommands
{
class ViewModel
{
}
}
ViewModel.cs:
MVVM
请有人帮助我一劳永逸地学习。我是{{1}}概念的新手,我已经阅读了很多但没有结果。我真的需要一个实用的解决方案才能使概念正确。
答案 0 :(得分:3)
你的Redraw方法应该做什么?如果某些属性发生变化,请更改边框例如。商店里的商品已售罄?
在一般视图中应反映ViewModel中的更改。这通过绑定自动发生。 View元素(如按钮)可以使用Commands与ViewModel进行通信。
因此,您的按钮看起来像这样:
<Button Command={Binding ClickCommand} />
在您的ViewModel中,您将拥有
public DelegateCommand ClickCommand {get; private set;}
和
ClickCommand = new DelegateCommand(ExecuteClick);
ExecuteClick会更新视图模型中的某些属性,例如如果您有在线商店,请将自行车对象的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转换为红色。
注意:SelectedItem再次绑定到一个列表,其源被绑定到像ViewModel上的ObservableCollection。
所以基本上你不应该调用重绘,它应该全部通过命令,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背景(或边框..)
答案 1 :(得分:0)
您可以使用Expression Blend提供的“CallMethodAction”行为。将System.Windows.Interactivity.dll添加到您的项目,您可以将方法绑定到事件。在您的情况下,“ReDraw”方法必须绑定到“Click”事件。有关此behavior的更多信息。
<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>