Reputation: 6882
I am trying to get the ancestor ItemsControl.ItemTemplate source as my DataGrid source but i could not handle the case. I tried the following case in my xaml. But it did not work and datagrid is empty.
Here is my xaml:
<ItemsControl ItemsSource="{Binding Accounts}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander ExpandDirection="Down" FlowDirection=" RightToLeft">
<Expander.Header>
<DataGrid FlowDirection="LeftToRight"
ItemsSource="{RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemTemplate}}}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding UserName}" />
<DataGridTextColumn Binding="{Binding Password}" />
</DataGrid.Columns>
</DataGrid>
</Expander.Header>
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
Accounts property implementation is like:
public List<User> Accounts = new List<User>();
Accounts.Add(new User("userName1","password1"));
Accounts.Add(new User("userName2","password2"));
And my User.cs is like:
public class User : INotifyPropertyChanged
{
public string UserName{get; set;}
public string Password{get; set;}
public UserAccount(string userName, string password)
{
UserName = userName;
Password = password;
}
}
Upvotes: 1
Views: 1921
Reputation: 35680
Basically, this code doesn't create a binding
ItemsSource="{RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemTemplate}}}"
also ancestor type is incorrect.
try this Binding:
ItemsSource="{Binding Path=DataContext.Accounts, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}}"
or use ElementName:
<ItemsControl Name="LstAccounts" ItemsSource="{Binding Accounts}">
and
ItemsSource="{Binding Path=DataContext.Accounts, ElementName=LstAccounts}"
code above fixes binding, but produces unexpected results. here is a solution to show a single object in a DataGrid
for ItemSource binding I created a converter (my own older answer)
public class ItemsSourceConverter: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
// doesn't allow to add new rows in DataGrid
return Enumerable.Repeat(value, 1).ToArray();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
and here is modified ItemsControl. Converter is stored in resources and used in ItemsSource binding. DataGrid autogenerates columns
<ItemsControl ItemsSource="{Binding Accounts}">
<ItemsControl.Resources>
<local:ItemsSourceConverter x:Key="Enumerator"/>
</ItemsControl.Resources>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander ExpandDirection="Down" FlowDirection=" RightToLeft">
<Expander.Header>
<DataGrid FlowDirection="LeftToRight"
ItemsSource="{Binding ., Converter={StaticResource Enumerator}}"/>
</Expander.Header>
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
here is a screenshot
Upvotes: 3