在 WPF 中的两个用户控件之间发送命令 [英] Send commands between two usercontrols in WPF

查看:35
本文介绍了在 WPF 中的两个用户控件之间发送命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将命令从一个 UserControl 发送到另一个.第一个包含一个按钮,第二个包含一个从 Border 类派生的自定义类.

I'm trying to send a command from one UserControl to another. The first one contains a button and the second one contains a custom class that derives from the Border class.

我想当我点击UserControl中的Button来执行CustomBorder中的Redraw method>UserControl2.

I want when I click the Button in UserControl to execute the Redraw method in CustomBorder in UserControl2.

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

Here is what I have done so far.

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>

UserControl1:

<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>

UserControl2:

<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 概念的新手,我已经阅读了很多但没有结果.我真的需要一个实用的解决方案来正确理解这些概念.

Please somebody help me learn this once and for all. I'm new to MVVM concept and I have read a lot but no results. I really need a practical solution to get the concepts right.

推荐答案

你的 Redraw 方法真正应该做什么?如果某些属性已更改,请更改边框?例如.商店里的商品售罄了?

What does your Redraw method is really supposed to do? Change border if some property has changed? E.g. an item in a shop was sold out?

一般来说,视图应该反映 ViewModel 中的变化.这通过绑定自动发生.视图元素,例如按钮,可以通过命令与 ViewModel 进行通信.

In general view should reflect changes in the ViewModel. This happens automatically with bindings. View element, such as button, can communicate with ViewModel with Commands.

因此您的按钮将如下所示:

Therefore your button would look like this:

<Button Command={Binding ClickCommand} />

在您的 ViewModel 中,您将拥有一个

In your ViewModel you'll have a

public DelegateCommand ClickCommand {get; private set;}

ClickCommand = new DelegateCommand(ExecuteClick);

ExecuteClick 会更新视图模型中的一些属性,例如如果您有在线商店,请将自行车对象的 SoldOut 属性设置为 true.

ExecuteClick would update some properties in the view model, e.g. if you have an online shop, set a SoldOut property of bike object to true.

如果某些属性发生变化,您的视图将依次绑定到 Bike 的属性并更改其外观.像文本这样的变化会自己发生,更复杂的变化可以通过转换器来实现(例如,在 SoldOut 中将 bckaground 更改为红色是正确的):

Your view will in turn bind to properties of Bike and change its appearance if some properties change. Changes like text will happen by themselves, more complicated changes can be achieved with converters (e.g. change bckaground to red in SoldOut is true):

<Resources>
 <SoldOutToBckgrConverter x:Key="soldOutToBckgrConverter" />
</Resources>
<Label Content={Binding Path=SelectedItem.Model} Background={Binding Path=SelectedItem.SoldOut, Converter={StaticResource soldOutToBckgrConverter}} />

SoldOutToBckgrConverter 实现 IValueConverter 并将 True 转换为 Red.

SoldOutToBckgrConverter implements IValueConverter and converts True to Red.

注意:SelectedItem 再次绑定到一个列表,其源绑定到诸如 ViewModel 上的 ObservableCollection 之类的东西.

Note: SelectedItem is again bound to a list, whose source is bound to sth like ObservableCollection on your ViewModel.

所以基本上你不应该调用重绘,它应该使用命令、VM 和绑定的更改自动重绘自己.

So basically you shouldn't call redraw, it should all redraw itself automatically with commands, changes in VM and bindings.

更新您的评论:鉴于我了解您重绘权利的目的,这就是我试图展示的内容.在我的示例中,已售商品的产品和红色背景将如下所示:

Update to your comment: that's what I tried to show, given that I understood the purpose of your redraw right. In my example with products and red background for sold items this will look like this:

在您的虚拟机中:

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.

MyProduct has Model property (real world product model, i.e. brand) and 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 更改背景(或边框..)

Now when you click you button, VM changes SelectedProduct and Binding cahnges background (or border..)

这篇关于在 WPF 中的两个用户控件之间发送命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆