简体   繁体   中英

WPF DataTemplate Binding to Content without Path - is this a bug?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM