如何将数据从 MainWindow 传递到 MainWindow 内的用户控件? [英] How to pass data from MainWindow to a User Control that's inside the MainWindow?

查看:25
本文介绍了如何将数据从 MainWindow 传递到 MainWindow 内的用户控件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的研究表明人们倾向于使用 ViewModel 来实现这一点,但我有点陷入困境.

I did my research that people tend to use ViewModel to achieve this but I am sort of stuck in it.

我有一个

public ObservableCollection订单列表{获取;放;} = new ObservableCollection();

在已经填满数据的MainWindow中.

在 MainWindow XAML 中,我在 TabControl 中有一个用户控件:

in MainWindow XAML I have a User Control inside the TabControl:

<TabControl x:Name="TabCollection">
        <TabItem Header="UC1">
            <local:UserControl1/>
        </TabItem>
        <TabItem Header="UC2">
            <local:UserControl2/>
        </TabItem>
    </TabControl>

我们这里只讨论 UC1,所以在 UC1 XAML 中我有一个 ListView 里面:

We only talk about UC1 here so in UC1 XAML here I have a ListView inside:

    <UserControl.DataContext>
    <local:UserControl1VM/>
</UserControl.DataContext>

<ListView x:Name="ListViewText">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="First name" DisplayMemberBinding="{Binding Firstname}"/>
            <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding Lastname}"/>
            <GridViewColumn Header="Order" DisplayMemberBinding="{Binding Ordername}"/>
            <GridViewColumn Header="Delivery time" DisplayMemberBinding="{Binding Deliverytime}"/>
            <GridViewColumn Header="Phone Number" DisplayMemberBinding="{Binding Phone}"/>
            <GridViewColumn Header="Address" DisplayMemberBinding="{Binding Address}"/>
            <GridViewColumn Header="Email" DisplayMemberBinding="{Binding Email}"/>
        </GridView>
    </ListView.View>
</ListView>

这是 UserControl1VM.cs 中的代码:

And here's the code in UserControl1VM.cs:

namespace QuickShop
{
class UserControl1VM : INotifyPropertyChanged
{
    private ObservableCollection<Order> orderList;
    public ObservableCollection<Order> OrderList
    {
        get { return orderList; }
        set
        {
            orderList = value;
            PropertyChanged(this, new PropertyChangedEventArgs("OrderList"));
        }
    }

    //
    private void FindDeliveryOrders(IEnumerable<Order> sortList)
    {
        foreach (var order in sortList)
        {
            if (order.Delivery.Equals("Yes"))
            {
                //deliveryOrders.Add(order);
                this.ListViewText.Items.Add(new Order { Firstname = order.Firstname, Lastname = order.Lastname, Ordername = order.Ordername, Deliverytime = order.Deliverytime, Phone = order.Phone, Address = order.Address, Email = order.Email });
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged = delegate { };
}
}

当然,这些都是不完整的代码,因为我不知道接下来如何进行.

And Of course these are incomplete codes because I don't know how to proceed next.

我的目标只是填充 ListView,如果 orderList 发生变化,它会自动更新.但是现在我什至不知道ViewModel是否工作,任何想法和代码演示都将非常感激.

My goal is just to populate the ListView and it will automatically update itself if orderList changes. But right now I couldn't even know whether the ViewModel is working or not, any thoughts and code demo would be very grateful.

推荐答案

UserControl 永远不应该有一个私有"控件视图模型,当您将其分配给 UserControl 的 XAML 中的 DataContext 时.相反,它应该公开可以绑定到外部提供的视图模型对象的属性的依赖属性.

A UserControl should never have a "private" view model, as you assign it to the DataContext in the UserControl's XAML. It should instead expose dependency properties that could be bound to properties of an externally provided view model object.

像这样声明一个 ItemsSource 属性:

Declare an ItemsSource property like this:

public partial class UserControl1 : UserControl
{
    public static readonly DependencyProperty ItemsSourceProperty =
        DependencyProperty.Register(
            nameof(ItemsSource), typeof(IEnumerable), typeof(UserControl1));

    public IEnumerable ItemsSource
    {
        get { return (IEnumerable)GetValue(ItemsSourceProperty); }
        set { SetValue(ItemsSourceProperty, value); }
    }

    public UserControl1()
    {
        InitializeComponent();
    }
}

然后像这样绑定 ListView:

And bind the ListView like this:

<UserControl ...>
    ...
    <ListView ItemsSource="{Binding ItemsSource,
                            RelativeSource={RelativeSource AncestorType=UserControl}}">
        ...
    </ListView>
    ...
</UserControl>

当您使用 UserControl 时,将属性绑定到视图模型属性:

When you use the UserControl, bind the property to a view model property:

<TabItem Header="UC1">
    <local:UserControl1 ItemsSource="{Binding OrderList}"/>
</TabItem>

最后一个 XAML 片段假定 UserControl 的 DataContext 中的对象具有 OrderList 属性.当 TabControl 绑定到具有该属性的视图模型对象集合时,这将自动发生.

The last XAML snippet assumes that the object in the UserControl's DataContext has a OrderList property. This would automatically happen when the TabControl is bound to a collection of view model objects with that property.

或者,让 UserControl 的 XAML 中的元素直接绑定到继承的 DataContext 中对象的属性.

Alternatively, let the elements in the UserControl's XAML directly bind to the properties of the object in the inherited DataContext.

<UserControl ...>
    ...
    <ListView ItemsSource="{Binding OrderList}">
        ...
    </ListView>
    ...
</UserControl>

您的控件不必公开其他可绑定属性,但它只能与实际提供预期源属性的 DataContext 对象一起使用.

Your control would not have to expose additional bindable properties, but it would only work with DataContext objects that actually provide the expected source properties.

这篇关于如何将数据从 MainWindow 传递到 MainWindow 内的用户控件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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