WPF ContentControl ничего не отображает

Я пытаюсь создать элемент управления, который выборочно отображает разные вещи в зависимости от переданных типов, но по какой-то причине я вообще ничего не отображаю.

Есть ли какая-то фундаментальная вещь, которую мне здесь не хватает? (Этот код сильно урезан из моего реального производственного приложения, но демонстрирует такое же поведение)

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new List<ContactInformation>
            {
                new Address {Street = "21 Jump", City = "Sparta", State = "Denial"},
                new Phone {Number = "734-555-1212"}
            };
    }
}

public class ContactInformation
{
}

public class Address : ContactInformation
{
    public string Street { get; set; }
    public string City { get; set; }
    public string State { get; set; }
}

public class Phone : ContactInformation
{
    public string Number { get; set; }
}

<Window x:Class="ContentControlExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:contentControlExample="clr-namespace:ContentControlExample"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ItemsControl ItemsSource="{Binding /}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <ContentControl DataContext="{Binding /}" Content="{Binding /}">
                        <ContentControl.Resources>
                            <DataTemplate DataType="{x:Type contentControlExample:Address}">
                                <StackPanel>
                                    <TextBlock Text="{Binding Street}"/>
                                    <TextBlock>
                                        <TextBlock.Text>
                                            <MultiBinding StringFormat="{}{0}, {1}">
                                                <Binding Path="City"/>
                                                <Binding Path="State"/>
                                            </MultiBinding>
                                        </TextBlock.Text>
                                    </TextBlock>
                                </StackPanel>
                            </DataTemplate>
                            <DataTemplate DataType="{x:Type contentControlExample:Phone}">
                                <TextBlock Text="{Binding Number}"/>
                            </DataTemplate>
                        </ContentControl.Resources>
                    </ContentControl>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Window>

person Matt    schedule 26.04.2013    source источник
comment
Я не знаю, что означает "{Binding /}", но я этим не пользуюсь. Просто измените это на "{Binding}".   -  person Federico Berasategui    schedule 26.04.2013
comment
Я никогда не видел, чтобы привязки использовали /, как у вас... возможно, это связано? Быстрый способ тестирования — просто переместить ваши DataTemplates в <Window.Resources> и оставить ItemsControl как <ItemsControl ItemsSource="{Binding }" />. По умолчанию ItemsControl уже рисует ваш элемент с ContentPresenter и должен использовать ваши неявные шаблоны для рисования каждого элемента. Если это не сработает, проверьте свое визуальное дерево и DataContext с помощью такого инструмента, как Snoop. вероятно, указать вам в правильном направлении.   -  person Rachel    schedule 26.04.2013
comment
/ означает текущий элемент коллекции, поэтому ‹ItemsControl ItemsSource={Binding /}› будет означать текущий элемент списка ContactInformation. Однако вам не нужны другие /.   -  person Phil    schedule 26.04.2013
comment
@Phil Если это так, то проблема, вероятно, заключается в том, что текущий элемент не имеет свойства текущего элемента, поэтому / не работает для вложенных привязок. Я уверен, что выводятся некоторые ошибки привязки, которые могут указать точное местонахождение проблемы :)   -  person Rachel    schedule 26.04.2013


Ответы (2)


Все, что вам нужно, это удалить пару «/» следующим образом:

XAML:

<Window x:Class="ContentControlExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:contentControlExample="clr-namespace:ContentControlExample"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ItemsControl ItemsSource="{Binding }">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <ContentControl DataContext="{Binding }" Content="{Binding }">
                        <ContentControl.Resources>
                            <DataTemplate DataType="{x:Type contentControlExample:Address}">
                                <StackPanel>
                                    <TextBlock Text="{Binding Street}"/>
                                    <TextBlock>
                                        <TextBlock.Text>
                                            <MultiBinding StringFormat="{}{0}, {1}">
                                                <Binding Path="City"/>
                                                <Binding Path="State"/>
                                            </MultiBinding>
                                        </TextBlock.Text>
                                    </TextBlock>
                                </StackPanel>
                            </DataTemplate>
                            <DataTemplate DataType="{x:Type contentControlExample:Phone}">
                                <TextBlock Text="{Binding Number}"/>
                            </DataTemplate>
                        </ContentControl.Resources>
                    </ContentControl>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Window>

Код позади:

namespace ContentControlExample
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new List<ContactInformation>
            {
                new Address {Street = "21 Jump", City = "Sparta", State = "Denial"},
                new Phone {Number = "734-555-1212"}
            };
        }
    }

    public class ContactInformation
    {
    }

    public class Address : ContactInformation
    {
        public string Street { get; set; }
        public string City { get; set; }
        public string State { get; set; }
    }

    public class Phone : ContactInformation
    {
        public string Number { get; set; }
    }
}

Выход:

Результат

Надеюсь, это поможет.

person FHnainia    schedule 26.04.2013
comment
Не уверен, в чем разница, которая у меня была, но это дало мне рабочие части, в которых я нуждался, спасибо. - person Matt; 27.04.2013
comment
@Matt Я пытаюсь заставить поле XamDataGrid использовать ContentControl, в котором я устанавливаю ContentTemplate на основе значения и получаю тот же результат, что и вы, ничего не появляется. Ошибки нет, но и сетки нет. У меня все это работает в стандартном WPF DataGrid. Но не могу заставить его работать в XamDataGrid. Я не вижу ничего в этом посте, что заставит его работать. Можете ли вы сказать мне, как вы заставили его работать? - person user2109254; 26.03.2016

Попробуйте немного изменить код. Это работает, потому что ItemsControl автоматически выбирает правильный DataTemplate в зависимости от типа привязанного элемента.

public class ViewModel
{
    public ViewModel()
    {
        this.Items = new List<ContactInformation>
                         {
                             new Address
                                 {
                                     Street = "21 Jump", 
                                     City = "Sparta", 
                                     State = "Denial"
                                 }, 
                             new Phone { Number = "734-555-1212" }
                         };
    }

    public List<ContactInformation> Items { get; set; }
}

<Window.DataContext>
    <contentControlExample:ViewModel/>
</Window.DataContext>
<Grid>
    <Grid.Resources>
        <DataTemplate DataType="{x:Type contentControlExample:Address}">
            <StackPanel>
                <TextBlock Text="{Binding Street}"/>
                <TextBlock>
                    <TextBlock.Text>
                        <MultiBinding StringFormat="{}{0}, {1}">
                            <Binding Path="City"/>
                            <Binding Path="State"/>
                        </MultiBinding>
                    </TextBlock.Text>
                </TextBlock>
            </StackPanel>
        </DataTemplate>
        <DataTemplate DataType="{x:Type contentControlExample:Phone}">
            <TextBlock Text="{Binding Number}"/>
        </DataTemplate>
    </Grid.Resources>

    <ItemsControl ItemsSource="{Binding Items}"/>
</Grid>

Или для привязки текущего элемента к элементу управления содержимым:

<Grid>
    ... resources

    <ContentControl Content="{Binding Items/}"/>
</Grid>
person Phil    schedule 26.04.2013
comment
Я попытаюсь вытащить элементы на модели просмотра. В реальном производственном коде элемент управления не используется. На самом деле я заполняю одну ячейку Infragistics XamDataGrid. ItemsControl демонстрировал такое же поведение, поэтому я использовал его в качестве примера. - person Matt; 26.04.2013
comment
Насколько я вижу, ваш код не отображает результаты, отличные от моих. Все по-прежнему пусто - person Matt; 26.04.2013