绑定值更改时未设置 WPF DataTrigger
WPF DataTrigger not setting when bound value changed
我有一个数据模板,它为 canvas ItemsPanel 在内部绘制的每个 NodePairViewModel 定义了一条显示线。当表示的 NodePairViewModel 的 IsChecked 属性 按照样式中定义的方式(见下文)更改时,线条颜色应该更改,但是当设置此 属性 时,颜色不会更改。 INotify属性Changed 已实施,我已验证此事件正在触发。我看不出有什么明显的错误,同样的设置适用于同样在同一个项目面板中绘制的 NodeViewModels。
<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>
并且 IsChecked 属性 本身
private bool ArcIsChecked = false;
public bool IsChecked
{
get
{
return ArcIsChecked;
}
set
{
ArcIsChecked = value;
RaisePropertyChanged("IsChecked");
}
}
您需要从 Line
移动默认值
<Line ... Stroke="Blue">
变成Style
作为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>
根据 Dependency Property Setting Precedence List
样式触发器在层次结构中低于本地值,因此它无法覆盖您的默认(本地)值
我有一个数据模板,它为 canvas ItemsPanel 在内部绘制的每个 NodePairViewModel 定义了一条显示线。当表示的 NodePairViewModel 的 IsChecked 属性 按照样式中定义的方式(见下文)更改时,线条颜色应该更改,但是当设置此 属性 时,颜色不会更改。 INotify属性Changed 已实施,我已验证此事件正在触发。我看不出有什么明显的错误,同样的设置适用于同样在同一个项目面板中绘制的 NodeViewModels。
<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>
并且 IsChecked 属性 本身
private bool ArcIsChecked = false;
public bool IsChecked
{
get
{
return ArcIsChecked;
}
set
{
ArcIsChecked = value;
RaisePropertyChanged("IsChecked");
}
}
您需要从 Line
<Line ... Stroke="Blue">
变成Style
作为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>
根据 Dependency Property Setting Precedence List
样式触发器在层次结构中低于本地值,因此它无法覆盖您的默认(本地)值