传递ObservableCollection< object>到UserControl [英] Pass a ObservableCollection<object> to UserControl
问题描述
我一直在试图概括将ObservableCollection传递给此处提供的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 Person
s.
Now, inside each of those ContentPresenter
s, 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< object>到UserControl的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!