I have a problem understanding the following behavior (tested in .Net 4.0)
First: The following example works as I expected: It shows a CheckBox inside a Button.
C#:
DataContext = new CheckBox();
XAML:
<Button Content="{Binding}"/>
Inside an ItemsControl with a Path ("MyProperty"), it works too:
C#:
DataContext = new { MyList = new List<object>() { new { MyProperty = new CheckBox() } } };
XAML:
<ItemsControl ItemsSource="{Binding Path=MyList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Path=MyProperty}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
But inside an ItemsControl without a Path, it replaces the Button and only shows the CheckBox:
C#:
DataContext = new { MyList = new List<CheckBox>() { new CheckBox() } };
XAML:
<ItemsControl ItemsSource="{Binding Path=MyList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Why this example doesn't work?? Is this a bug in WPF? Thanks a lot for helping!
This is not a bug. The DataTemplate
isn't applied to ContentControls
. That's why your sample code doesn't work when the DataContext
of an item in the ItemsControl
is a CheckBox
but it does work when the DataContext
is an object
.
You are not supposed to define user interface elements in the DataContext
/view model.
I wouldn't consider the described behavior as WPF/XAML-bug.
ItemsControl (compared to ListView or ListBox) has no default ItemContainer (as ListViewItem or ListboxItem). With ListBox or ListView your example will work.
If you have a List<Textbox>
as ItemsSource
, then ItemsControl
uses items from ItemsSource
as ItemContainers so TextBoxes will be ItemContainers and you become
System.Windows.Data Error: 26 : ItemTemplate and ItemTemplateSelector are ignored for items already of the ItemsControl's container type; Type='CheckBox'
in your debug output so you DataTemplate will be ignored(without specifying ItemTemplate you will have the same issue).
To solve it you could derive from ItemsControl
and override IsItemItsOwnContainerOverride method:
Determines if the specified item is (or is eligible to be) its own container
Thanks a lot for your answers!
I didn't know the method IsItemItsOwnContainerOverride. If I override it and always return true then all works as I have expected.
I know, that this way of implementation is not the best one. But now I understand the behavior and I'm happy ;)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.