Search code examples
wpfxamldata-bindingmultidatatrigger

Must have non-null value for 'Setter.Property'


I am reading this article on MSDN site, in order to understand DataTrigger.

I have created a DefaultViewModel class which looks like this.

namespace ControlTemplateDemo
{
    public class DefaultViewModel
    {
        private List<ToDoItem> _list;

        public DefaultViewModel()
        {
            _list = new List<ToDoItem>();
            _list.Add(new ToDoItem { TaskName="Wedding",Priority = 1,Description="Important wedding",TypeOfTask = TaskType.Home});
            _list.Add(new ToDoItem { TaskName = "Toyota Meeting", Priority = 3, Description = "WSR", TypeOfTask = TaskType.Work });
        }

        public List<ToDoItem> Tasks
        {
            get { return _list; }
        }
    }
}

and my xaml code is presented below.

<Window x:Class="ControlTemplateDemo.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:local="clr-namespace:ControlTemplateDemo"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>

<DataTemplate  DataType="{x:Type local:ToDoItem}">
    <Border BorderThickness="1"  Name="myBorder" Margin="5" Padding="5" BorderBrush="Aqua">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <TextBlock Text="Task Name" Grid.Row="0" Grid.Column="0"/>
            <TextBlock Text="{Binding TaskName}" Grid.Row="0" Grid.Column="1"/>

            <TextBlock Text="Description:" Grid.Row="1" Grid.Column="0"/>
            <TextBlock Text="{Binding Description}" Grid.Row="1" Grid.Column="1" />

            <TextBlock Text="Priority:" Grid.Row="2" Grid.Column="0"/>
            <TextBlock Text="{Binding Priority}"  Grid.Row="2" Grid.Column="1"/>
        </Grid>
    </Border>
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding Path=TypeOfTask}">
            <DataTrigger.Value>
                <local:TaskType>Home</local:TaskType>
            </DataTrigger.Value>
            <Setter TargetName="myBorder" Property="Background" Value="Yellow" />
        </DataTrigger>

        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding Path=Priority}">
                    <Condition.Value>
                        <sys:Int32>3</sys:Int32>
                    </Condition.Value>
                </Condition>
                <Condition Binding="{Binding Path=Description}">
                    <Condition.Value>
                        <sys:String>WSR</sys:String>
                    </Condition.Value>
                </Condition>
            </MultiDataTrigger.Conditions>
            <Setter>
                <Setter.TargetName>myBorder</Setter.TargetName>
                <Setter.Property>Background</Setter.Property>
                <Setter.Value>Green</Setter.Value>
            </Setter>
        </MultiDataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

<!--<local:DefaultViewModel x:Key="dvm"/>-->
</Window.Resources>
    <Grid>
        <StackPanel>
            <TextBlock Name="blah" FontSize="20" Text="My To do tasks."/>
            <ListBox x:Name="lstTasks" ItemsSource="{Binding Path=Tasks}" HorizontalContentAlignment="Stretch" >
            </ListBox>
        </StackPanel>
    </Grid>
</Window>

I am using a DataTemplate to reder data inside ListBox. My intention is to highlight background of border (border of list item) depending on multiple conditions. e.g. if TaskPriorty is 3 and TaskDescription is 'WSR' then I want to highlight that list item with red color. However when I am running this application I am getting runtime error with below message.

Must have non-null value for 'Setter.Property'.

Without MultiDataTrigger everything is working fine.


Solution

  • Use attribute syntax instead of property element syntax

    <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
        ...
        </MultiDataTrigger.Conditions>
        <Setter TargetName="myBorder" Property="Background" Value="Green"/>
    </MultiDataTrigger>