c# - 在 WPF 中的两个用户控件之间发送命令

标签 c# wpf xaml mvvm user-controls

我正在尝试从一个 UserControl 发送命令给另一个。第一个包含一个按钮,第二个包含一个从 Border 派生的自定义类。类(class)。

我想要当我点击ButtonUserControl执行Redraw methodCustomBorderUserControl2 .

这是我到目前为止所做的。

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/

相关文章:

c# - 在 C# 中将二进制数据写入标准输出?

wpf - 是否可以在 C# 中显示、隐藏和操作 Windows 8 屏幕键盘?

xaml - UWP MVVM XAML 动态用户控制管理器

c# - 在所有 Quartz .NET IInterruptableJob 上触发中断

c# - 是否可以将背景位置添加到 img/asp :image tag

c# - 如何使用 ToolTipService.Duration 使 WPF ToolTip 显示得更快?

wpf - 在资源中分配和使用 WPF DataContext 的正确方法

c# - 无法在 WPF 圆形按钮 (XAML) 中获取边框

wpf - 为数据网格行创建上下文菜单

c# - 网络核心 : Generic Repository Primary Id Key Performance in Entity Framework