简体   繁体   English

为什么ListBox ItemTemplateSelector =“ {StaticResource MyDataTemplateSelector}”不能与资源一起使用?

[英]Why is the ListBox ItemTemplateSelector=“{StaticResource MyDataTemplateSelector}” not working with the resource?

Subject: I'm learning the DataTemplate concept by using a Microsoft example found here: https://docs.microsoft.com/en-us/dotnet/framework/wpf/data/data-templating-overview and on GitHub here: https://github.com/Microsoft/WPF-Samples/tree/master/Data%20Binding/DataTemplatingIntro 主题:我正在通过使用以下Microsoft示例来学习DataTemplate概念: https : //docs.microsoft.com/zh-cn/dotnet/framework/wpf/data/data-templating-overview和GitHub上的https://github.com/Microsoft/WPF-Samples/tree/master/Data%20Binding/DataTemplatingIntro

Issue: Xaml Design window displays error. 问题:Xaml设计窗口显示错误。

Error: NullReferenceException: Object reference not set to an instance of an object. 错误:NullReferenceException:对象引用未设置为对象的实例。

And from the top of the stack at the exception: 并且从堆栈顶部开始例外:

at BindingTest.TaskListDataTemplateSelector.SelectTemplate(Object item, DependencyObject container) 在BindingTest.TaskListDataTemplateSelector.SelectTemplate处(对象项,DependencyObject容器)

Specifics: Error appears after creating class TaskListDataTemplateSelector and adding these two lines: 详细信息:创建类TaskListDataTemplateSelector并添加以下两行后,将出现错误:

<Window.Resources>

    <local:TaskListDataTemplateSelector x:Key="MyDataTemplateSelector"/>

</Window.Resources>

and

<ListBox ....

   ItemTemplateSelector="{StaticResource MyDataTemplateSelector}"

</ListBox>

Further info: The example from Microsoft has the same issue. 进一步的信息:Microsoft的示例具有相同的问题。

Window x:Class="BindingTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:BindingTest"
    mc:Ignorable="d"
    Title="MainWindow"  Width="525" SizeToContent="WidthAndHeight">

<Window.Resources>
    <local:Tasks x:Key="myTodoList"/>
    <local:TaskListDataTemplateSelector x:Key="MyDataTemplateSelector"/>

    <DataTemplate x:Key="importantTaskTemplate">
        <DataTemplate.Resources>
            <Style TargetType="TextBlock">
                <Setter Property="FontSize" Value="20"/>
            </Style>
        </DataTemplate.Resources>
        <Border Name="border" BorderBrush="Red" BorderThickness="1"
                Padding="5" Margin="5">
            <DockPanel HorizontalAlignment="Center">
                <TextBlock Text="{Binding Path=Description}"/>
                <TextBlock>!</TextBlock>
            </DockPanel>
        </Border>
    </DataTemplate>

    <DataTemplate x:Key="myTaskTemplate">
        <Border Name="border" BorderBrush="Aqua" BorderThickness="1"
               Padding="5" Margin="5">
            <Grid ShowGridLines="false">
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Row="0" Grid.Column="0"  Text="Task Name:"/>
                <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=Name}"/>
                <TextBlock Grid.Row="1" Grid.Column="0"  Text="Description:"/>
                <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=Description}"/>
                <TextBlock Grid.Row="2" Grid.Column="0"  Text="Priority:"/>
                <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Path=Priority}"/>
            </Grid>
        </Border>

        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding Path=TaskType}">
                <DataTrigger.Value>
                    <local:TaskType>Home</local:TaskType>
                </DataTrigger.Value>
                <Setter TargetName="border" Property="BorderBrush" Value="Yellow"/>
            </DataTrigger>
        </DataTemplate.Triggers>

    </DataTemplate>
</Window.Resources>

<Grid>
    <StackPanel>
        <TextBlock FontSize="20" Text="My Task List"/>

        <ListBox Width="400" Margin="10"
                 ItemsSource="{Binding Source={StaticResource myTodoList}}"
                 ItemTemplateSelector="{StaticResource MyDataTemplateSelector}"
                   HorizontalContentAlignment="Stretch">
        </ListBox>
    </StackPanel>

</Grid>

 public   class TaskListDataTemplateSelector : DataTemplateSelector
{
    public override DataTemplate
      SelectTemplate(object item, DependencyObject container)
    {
        if (item != null && item is Task)
        {
            var taskitem = (Task)item;
            var window = Application.Current.MainWindow;
            if (taskitem.Priority == 1)
                return
                    window.FindResource("ImportantTaskTemplate") as DataTemplate;
            return
                window.FindResource("MyTaskTemplate") as DataTemplate;
        }

        return null;
    }
}

I found an error. 我发现一个错误。 It was a spelling issue: specifically capitalization. 这是一个拼写问题:特别是大写。

The spelling of MyTaskTemplate and ImportantTaskTemplate were not consistent throughout the project. MyTaskTemplate和ImportantTaskTemplate的拼写在整个项目中不一致。

The project now compiles and runs but still getting same exception in the Xaml Design window. 现在,该项目可以编译并运行,但是在Xaml Design窗口中仍然会出现相同的异常。

More digging revealed the fix for the Null Reference Exception error in the Xaml design window. 进一步的挖掘揭示了Xaml设计窗口中对Null Reference Exception错误的修复。 Thanks to Chris Anderson and his book: Essential Windows Presentation Foundation page 341. Replaced TaskListDataTemplateSelector with this: 感谢Chris Anderson和他的书:Essential Windows Presentation Foundation页面341。用以下内容代替TaskListDataTemplateSelector:

 public class TaskListDataTemplateSelector : DataTemplateSelector
{

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item != null && item is Task)
        {
            var taskitem = (Task)item;
            var window = Application.Current.MainWindow;
            if (taskitem.Priority == 1)
                return ((FrameworkElement)container).FindResource
                    ("ImportantTaskTemplate") as DataTemplate;

            return
            ((FrameworkElement)container).FindResource
                    ("MyTaskTemplate") as DataTemplate;
        }
        return null;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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