Pregunta

I am trying to build a Control that selectively displays different things based upon the types that are passed in, but for some reason I end up displaying nothing at all.

Is there some fundamental thing that I am missing here? (This code is massively stripped down from my real production app bu exhibits the same behavior)

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>
¿Fue útil?

Solución

All you need is to remove a couple of '/' as follow:

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>

The Code behind:

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; }
    }
}

The Ouput:

Result

I hope this helps.

Otros consejos

Try changing your code slightly. This works because the ItemsControl automatically picks the correct DataTemplate based on the type of the item being bound to.

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>

Or to bind the current item to a content control:

<Grid>
    ... resources

    <ContentControl Content="{Binding Items/}"/>
</Grid>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top