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>