2010-11-12 88 views
1

我有一个ObservableCollection<User>完整的用户对象,实现INotifyPropertyChanged。该集合被设置为我的窗口的DataContext,其中包含ListBox(其ItemsSource也设置为相同的集合),TextBox es以及标准CRUD设置的保存Button如何根据ObservableCollection中的INotifyPropertyChanged对象的属性更改元素的属性?

如果User对象的某个属性发生更改,我想更改save Button的背景(以及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

您列表框中每个项目的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> 

这是当应用程序运行它的外观:

DataTrigger Binding Example

+0

S如何使用绑定来更改“脏”物品的背景? – epalm 2010-11-12 21:40:45

+0

我已经用一个如何实现你所需要的行为的例子更新了我的答案。 – Murven 2010-11-14 06:04:50

0

WPF支持“当前项目”的想法,在一个收集,并将为您追踪当前项目。您可以编写一个引用集合当前项目的绑定路径。

请参阅MSDN上Data Binding Overview页面上的“当前项目指针”部分。

我在想,如果你的ListBox的ItemsSource绑定到(例如){Binding ListOfUsers},那么你的按钮可以使用{Binding ListOfUsers/IsDirty}

我还没有使用过这么多,但我认为你可能必须将你的ListBox的IsSynchronizedWithCurrentItem属性设置为True来使这个工作。

相关问题