简体   繁体   中英

WPF DataTrigger not setting when bound value changed

I have a data template which defines a line to display for every NodePairViewModel drawn inside by a canvas ItemsPanel. The line colour should change when the IsChecked Property of the NodePairViewModel being represented changes as defined in the style (see below) however when this property is set the colour does not change. INotifyPropertyChanged is implemented and I have verified that this event is firing. I cannot see anything obviously wrong and the same setup works for NodeViewModels which are also drawn in the same itemspanel.

    <DataTemplate DataType="{x:Type vm:NodePairViewModel}">
        <Line Canvas.ZIndex="2" Name="Arc" Stroke="Blue" StrokeThickness="3" 
              X1="{Binding Path=NodeA.PositionX, Mode=OneWay, Converter={StaticResource NodeLinkXConverter}}" 
              X2="{Binding Path=NodeB.PositionX, Mode=OneWay, Converter={StaticResource NodeLinkXConverter}}" 
              Y1="{Binding Path=NodeA.PositionY, Mode=OneWay, Converter={StaticResource NodeLinkYConverter}}" 
              Y2="{Binding Path=NodeB.PositionY, Mode=OneWay, Converter={StaticResource NodeLinkYConverter}}" 
              MouseLeftButtonDown="Arc_MouseLeftButtonDown" MouseLeftButtonUp="Arc_MouseLeftButtonUp">
            <Line.Style>
                <Style TargetType="Line">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=IsChecked}" Value="True">
                            <Setter Property="Stroke" Value="Orange"></Setter>
                            </DataTrigger>

<DataTrigger Binding="{Binding Path=IsSelected, Mode=OneWay}" Value="True">
                                <Setter Property="Stroke" Value="Red"/>
                            </DataTrigger>
                            <DataTrigger Binding="{Binding Path=IsRejected, Mode=OneWay}" Value="True">
                                <Setter Property="Stroke" Value="LightGray"/>
                            </DataTrigger>
                            <DataTrigger Binding="{Binding Path=IsVisited}" Value="True">
                                <Setter Property="Stroke" Value="LightGreen"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Line.Style>
            </Line>
        </DataTemplate>


<ItemsControl Name="NodeSpace" ItemsSource="{Binding GraphItems}" Margin="5" MouseMove="NodeSpace_MouseMove" MouseDown="NodeSpace_MouseDown" MouseLeftButtonUp="NodeSpace_MouseLeftButtonUp" MouseLeftButtonDown="NodeSpace_MouseLeftButtonDown" MouseRightButtonDown="NodeSpace_MouseRightButtonDown" RenderTransformOrigin="0.5,0.5" Grid.Column="1" Grid.Row="1">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <Canvas Name="GraphSurface" Background="#FFFFFE"></Canvas>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemContainerStyle>
                        <Style TargetType="ContentPresenter">
                            <Setter Property="Canvas.Left">
                                <Setter.Value>
                                    <Binding Mode="OneWay" Path="PositionX" Converter="{StaticResource XInverseConverter}"/>
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Canvas.Top">
                                <Setter.Value>
                                    <Binding Mode="OneWay" Path="PositionY" Converter="{StaticResource YInverseConverter}"/>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </ItemsControl.ItemContainerStyle>
                </ItemsControl>

And the IsChecked property itself

private bool ArcIsChecked = false;
public bool IsChecked 
{
    get
    {
        return ArcIsChecked;
    }
    set
    {
        ArcIsChecked = value;
        RaisePropertyChanged("IsChecked");
    }
}

You need to move default value from Line

<Line ... Stroke="Blue">

into Style as Setter

<Line 
   Canvas.ZIndex="2" 
   Name="Arc" 
   StrokeThickness="3" 
   X1="{Binding Path=NodeA.PositionX, Mode=OneWay, Converter={StaticResource NodeLinkXConverter}}" 
   X2="{Binding Path=NodeB.PositionX, Mode=OneWay, Converter={StaticResource NodeLinkXConverter}}" 
   Y1="{Binding Path=NodeA.PositionY, Mode=OneWay, Converter={StaticResource NodeLinkYConverter}}" 
   Y2="{Binding Path=NodeB.PositionY, Mode=OneWay, Converter={StaticResource NodeLinkYConverter}}" 
   MouseLeftButtonDown="Arc_MouseLeftButtonDown" 
   MouseLeftButtonUp="Arc_MouseLeftButtonUp">
   <Line.Style>
      <Style TargetType="{x:Type Line}">
         <Setter Property="Stroke" Value="Blue"/>
         <Style.Triggers>
            <DataTrigger Binding="{Binding Path=IsChecked}" Value="True">
               <Setter Property="Stroke" Value="Orange"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=IsSelected, Mode=OneWay}" Value="True">
               <Setter Property="Stroke" Value="Red"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=IsRejected, Mode=OneWay}" Value="True">
               <Setter Property="Stroke" Value="LightGray"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=IsVisited}" Value="True">
               <Setter Property="Stroke" Value="LightGreen"/>
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </Line.Style>
</Line>

according to Dependency Property Setting Precedence List style trigger is lower in hierarchy then local value so it won't be able to overwrite your default (local) value

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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