繁体   English   中英

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

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

主题:我正在通过使用以下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

问题:Xaml设计窗口显示错误。

错误:NullReferenceException:对象引用未设置为对象的实例。

并且从堆栈顶部开始例外:

在BindingTest.TaskListDataTemplateSelector.SelectTemplate处(对象项,DependencyObject容器)

详细信息:创建类TaskListDataTemplateSelector并添加以下两行后,将出现错误:

<Window.Resources>

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

</Window.Resources>

<ListBox ....

   ItemTemplateSelector="{StaticResource MyDataTemplateSelector}"

</ListBox>

进一步的信息: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;
    }
}

我发现一个错误。 这是一个拼写问题:特别是大写。

MyTaskTemplate和ImportantTaskTemplate的拼写在整个项目中不一致。

现在,该项目可以编译并运行,但是在Xaml Design窗口中仍然会出现相同的异常。

进一步的挖掘揭示了Xaml设计窗口中对Null Reference Exception错误的修复。 感谢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