传递ObservableCollection< object>到UserControl [英] Pass a ObservableCollection<object> to UserControl

查看:47
本文介绍了传递ObservableCollection< object>到UserControl的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在试图概括将ObservableCollection传递给此处提供的UserControl的解决方案:

如何在UserControl中绑定集合依赖项属性

我将UserControl背后的代码更改为:

 ///< summary>///myUserControl1.xaml的交互逻辑///</summary>公共局部类myUserControl1:UserControl{#region公共部分公共ObservableCollection< object>UC项目{得到;放;}#endregion公共myUserControl1(){InitializeComponent();UCItems =新的ObservableCollection< object>();}#region UCItemsSource属性公共静态只读DependencyProperty UCItemsSourceProperty =DependencyProperty.Register("UCItemsSource",typeof(IEnumerable),typeof(myUserControl1));公共IEnumerable UCItemsSource{获取{返回(IEnumerable)GetValue(UCItemsSourceProperty);}设置{SetValue(UCItemsSourceProperty,value);}}#endregion} 

并将TexBox更改为xaml中的DataGrid:

 < UserControl x:Class ="OCasDPdemo.myUserControl1";xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"xmlns:local ="clr-namespace:OCasDPdemo";mc:Ignorable ="d"d:DesignHeight ="450".d:DesignWidth ="800">.<网格>< ItemsControl ItemsSource =" {Binding Path = UCItemsSource,RelativeSource = {RelativeSource Mode = FindAncestor,AncestorType = {x:Type UserControl}}}"< ItemsControl.ItemTemplate>< DataTemplate>< DataGrid x:Name ="myDataGrid";ItemsSource ="{Binding Path = UCItemsSource.Person}"/></DataTemplate></ItemsControl.ItemTemplate></ItemsControl></Grid> 

我以与原始示例类似的方式填充集合:

 ///< summary>///MainWindow.xaml的交互逻辑///</summary>公共局部类MainWindow:Window{公共ObservableCollection< Person>WindowCollection{得到;放;}公共MainWindow(){InitializeComponent();DataContext = this;var bob = new Person {FirstName ="Bob",LastName ="Brown",Age = 32.1,ID = 101};var jim = new Person {FirstName ="Jim",LastName ="Green",Age = 21.0,ID = 201};var mel = new Person {FirstName ="Mel",LastName ="Black",Age = 20,ID = 111};WindowCollection =新的ObservableCollection< Person>(){bob,jim,mel};}私有void Button_Click(对象发送者,RoutedEventArgs e){var sue = new Person {FirstName ="Sue",LastName ="White",Age = 64.7,ID = 101};var ted = new Person {FirstName ="Ted",LastName ="Grey",Age = 18.3,ID = 191};WindowCollection.Add(sue);WindowCollection.Add(ted);}} 

MainWindow xaml是:

 < Grid>< StackPanel>< local:myUserControl1 UCItemsSource =< {Binding Path = WindowCollection}"/><按钮内容=刷新";点击="Button_Click"/></StackPanel></Grid> 

我得到的是空行(与人数相同),而不是带有列的网格.此设置适用于本机类型,例如长型和字符串类型(使用TextBox).有人可以让我知道我做错了吗.

解决方案

我自己还没有尝试过,但是问题似乎出在您的 myUserControl1 XAML中.

仅在根 Grid 内部是一个 ItemsControl ,其中 ItemsSource 绑定到 UCItemsSource .这意味着 ItemsControl 将为该集合中的每个元素生成一个 ContentPresenter -在您的情况下,这将是您的 Person s列表.

现在,在每个 ContentPresenter 中,将创建 DataTemplate 的实例.您的 DataTemplate 包含一个 DataGrid .这意味着您将为每个 Person 人员获得一个完整的 DataGrid .

如果相反,您尝试使用一个 DataGrid ,每个 Person 一行,则可能需要这样的内容:

 < UserControl x:Class ="OCasDPdemo.myUserControl1";xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"xmlns:local ="clr-namespace:OCasDPdemo";mc:Ignorable ="d"d:DesignHeight ="450".d:DesignWidth ="800">.<网格>< DataGrid x:Name ="myDataGrid";ItemsSource ="{Binding Path = UCItemsSource,RelativeSource = {RelativeSource Mode = FindAncestor,AncestorType = {x:Type UserControl}}}"</DataGrid></Grid></UserControl> 

I have been trying to generalize the solution for passing ObservableCollection to a UserControl provided here:

How to bind collection dependency property in UserControl

I changed the code behind UserControl to:

/// <summary>
/// Interaction logic for myUserControl1.xaml
/// </summary>
public partial class myUserControl1 : UserControl
{
    #region Public Section
    public ObservableCollection<object> UCItems
    {
        get;
        set;
    }

    #endregion
    public myUserControl1()
    {
        InitializeComponent();

        UCItems = new ObservableCollection<object>();
    }

    #region UCItemsSource Property

    public static readonly DependencyProperty UCItemsSourceProperty = 
        DependencyProperty.Register("UCItemsSource", typeof(IEnumerable), typeof(myUserControl1));

    public IEnumerable UCItemsSource
    {
        get { return (IEnumerable)GetValue(UCItemsSourceProperty); }
        set { SetValue(UCItemsSourceProperty, value); }
    }

    #endregion
}

and changed TexBox to DataGrid in xaml:

<UserControl x:Class="OCasDPdemo.myUserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:OCasDPdemo"
         mc:Ignorable="d" 
         d:DesignHeight="450" d:DesignWidth="800">
<Grid>
    <ItemsControl ItemsSource="{Binding Path=UCItemsSource, 
                                    RelativeSource={RelativeSource Mode=FindAncestor,
                                                                   AncestorType={x:Type UserControl}}}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <DataGrid x:Name="myDataGrid" ItemsSource="{Binding Path=UCItemsSource.Person}"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

I populate the collection in a similar way to the original example:

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public ObservableCollection<Person> WindowCollection
    {
        get;
        set;
    }
    public MainWindow()
    {
        InitializeComponent();

        DataContext = this;


        var bob = new Person { FirstName = "Bob", LastName = "Brown", Age = 32.1, ID = 101 };
        var jim = new Person { FirstName = "Jim", LastName = "Green", Age = 21.0, ID = 201 };
        var mel = new Person { FirstName = "Mel", LastName = "Black", Age = 20, ID = 111 };

        WindowCollection = new ObservableCollection<Person>() {bob, jim, mel };
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var sue = new Person { FirstName = "Sue", LastName = "White", Age = 64.7, ID = 101 };
        var ted = new Person { FirstName = "Ted", LastName = "Grey", Age = 18.3, ID = 191 };

        WindowCollection.Add(sue);
        WindowCollection.Add(ted);
    }
}

and MainWindow xaml is:

<Grid>
    <StackPanel>
        <local:myUserControl1 UCItemsSource="{Binding Path=WindowCollection}" />
        <Button Content="Refresh" Click="Button_Click" />
    </StackPanel>
</Grid>

I am getting empty lines (same as the number of persons) instead of grid with columns. This setup works with native types like long and string types (with TextBox). Could somebody please let me know what I am doing wrong.

解决方案

I haven't tried this out myself, but the problem seems to be in your myUserControl1 XAML.

Just inside the root Grid is an ItemsControl with the ItemsSource bound to UCItemsSource. This means the ItemsControl will generate one ContentPresenter for each element in that collection- which in your case will be your list of Persons.

Now, inside each of those ContentPresenters, an instance of your DataTemplate will be created. Your DataTemplate contains a DataGrid. This means you will get one entire DataGrid per Person.

If instead you are trying to have one DataGrid with one row per Person, you might want something like this:

<UserControl x:Class="OCasDPdemo.myUserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:OCasDPdemo"
         mc:Ignorable="d" 
         d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <DataGrid x:Name="myDataGrid" ItemsSource="{Binding Path=UCItemsSource, 
                                                        RelativeSource={RelativeSource Mode=FindAncestor,
                                                                                       AncestorType={x:Type UserControl}}}">
            
        </DataGrid>
    </Grid>
</UserControl>

这篇关于传递ObservableCollection&lt; object&gt;到UserControl的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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