我有一个ObservableCollection<User>
个用户对象来实现INotifyPropertyChanged
。该集合设置为我的窗口的DataContext
,其中包含ListBox
(其ItemsSource
也设置为相同的集合),多个TextBox
es,以及保存Button
,标准CRUD设置。
如果User对象的某个属性发生更改,我想更改保存按钮的背景(以及ListBox中与“当前项目”对应的行的背景)。我应该看看风格和触发器吗?
我将以下样式应用于我的保存按钮,而用户对象具有public bool IsDirty
属性。
<Style x:Key="PropertyChangedStyle" TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding Source=???, Path=IsDirty}" Value="True">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
<Button ... Style="{StaticResource PropertyChangedStyle}">
我认为我走在正确的轨道上,但我不明白如何将绑定指向“设置为datacontext的可观察列表中的当前项目”,其中“当前项目”在这种情况下是由CollectionViewSource.GetDefaultView(ListOfUsers).CurrentItem
描述(其中ListOfUsers
是我的ObservableCollection<User>
)。
答案 0 :(得分:0)
ListBox中每个项目的DataContext
将自动绑定到User
个实例,因此无需在绑定中设置源代码。您可以直接从ListBoxItem
的样式绑定到User
个实例的属性。
你可以这样做:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ASD_Answer011.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Window.Resources>
<DataTemplate x:Key="ItemTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Property1}"/>
<CheckBox IsChecked="{Binding Property2}"/>
</StackPanel>
</DataTemplate>
<Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsDirty}" Value="True">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Padding" Value="2,0,0,0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="Selector.IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource SampleDataSource}}">
<ListBox ItemTemplate="{DynamicResource ItemTemplate}" ItemsSource="{Binding Collection}" ItemContainerStyle="{DynamicResource ListBoxItemStyle1}"/>
</Grid>
</Window>
这是应用程序运行时的外观:
答案 1 :(得分:0)
WPF支持集合中“当前项目”的想法,并将为您跟踪当前项目。您可以编写引用集合当前项的绑定路径。
请参阅MSDN上Data Binding Overview页面上的“当前项目指针”部分。
我在想,如果您的ListBox的ItemsSource被绑定(例如){Binding ListOfUsers}
,那么您的按钮可以使用{Binding ListOfUsers/IsDirty}
。
我没有使用过这么多,但我认为您可能必须将ListBox的IsSynchronizedWithCurrentItem属性设置为True才能使其正常工作。