根据数据更改样式

时间:2013-04-23 20:46:39

标签: c# wpf xaml mvvm datatemplate

考虑以下XAML =>

        <fluent:Ribbon x:Name="MenuRibbon"
                       Title="title"
                       SnapsToDevicePixels="True">
        <fluent:RibbonTabItem x:Name="Home"
                                  Header="Home">
            <fluent:RibbonGroupBox Header="Project">
                <fluent:InRibbonGallery MinItemsInRow="3"
                                            MaxItemsInRow="6"
                                            Width="300"
                                            ItemWidth="64"
                                            ItemHeight="56"
                                            ItemsSource="{Binding Projects}">
                    <fluent:InRibbonGallery.ItemTemplate>
                        <DataTemplate>
                            <DockPanel>
                                <Border BorderBrush="{x:Null}"  Height="56">

                                    <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" DockPanel.Dock="Bottom"
                                               Text="{Binding Name}">
                                    </TextBlock>
                                </Border>
                            </DockPanel>
                        </DataTemplate>
                    </fluent:InRibbonGallery.ItemTemplate>
                </fluent:InRibbonGallery>
            </fluent:RibbonGroupBox>
        </fluent:RibbonTabItem>
    </fluent:Ribbon>

我将ObservableColleciton of Projects绑定到InRibbonGallery,并且ViewModel中存在一个项目实例(ActiveProject)。
在DataTemplate中定义的TextBlock,用于显示Project对象的名称 如何更改包含Active Project的TextBlock的颜色?
ViewModel:

public class ViewModel : ViewModelBase
{
    private ObservableCollection<Project> _projects;

    public ViewModel()
    {
        Projects = new ObservableCollection<Project>(new List<Project>
                                                         {
                                                             new Project {Id = "0", Name = "Project1"},
                                                             new Project {Id = "1", Name = "Project2"},
                                                             new Project {Id = "2", Name = "Project3"}
                                                         });
        Project = Projects[0];
    }

    public ObservableCollection<Project> Projects
    {
        get { return _projects; }
        set
        {
            _projects = value;
            RaisePropertyChanged(() => Projects);
        }
    }

    public Project Project { get; set; }
}

public class Project : ObservableObject
{
    private string _id;
    private string _name;

    public string Name

    {
        get { return _name; }
        set
        {
            _name = value;
            RaisePropertyChanged(() => Name);
        }
    }

    public string Id
    {
        get { return _id; }
        set
        {
            _id = value;
            RaisePropertyChanged(() => Id);
        }
    }
}

位于here的项目文件。

1 个答案:

答案 0 :(得分:1)

您可以使用MultiBindingDataTrigger组合来获得更好的结果。

所以你的xaml看起来像:

<Window.Resources>
  <vm:ViewModel x:Key="ViewModel" />
  <vm:ActiveProjectCheckConverter x:Key="ActiveProjectCheckConverter" />
</Window.Resources>
...
<TextBlock HorizontalAlignment="Center"
            VerticalAlignment="Center"
            DockPanel.Dock="Bottom"
            Text="{Binding Name}">
  <TextBlock.Style>
    <Style TargetType="{x:Type TextBlock}">
      <Setter Property="Background"
              Value="Transparent" />
      <Style.Triggers>
        <DataTrigger Value="True">
          <DataTrigger.Binding>
            <MultiBinding Converter="{StaticResource ActiveProjectCheckConverter}">
              <Binding Path="Name" />
              <Binding Path="DataContext.ActiveProject.Name"
                        RelativeSource="{RelativeSource FindAncestor,
                                                        AncestorType={x:Type fluent:InRibbonGallery}}" />
            </MultiBinding>
          </DataTrigger.Binding>
          <Setter Property="Background">
            <Setter.Value>
              <LinearGradientBrush StartPoint="1,0">
                <GradientStop Offset="0.0"
                              Color="#00FFFFFF" />
                <GradientStop Offset="1.1"
                              Color="#FFFFFFFF" />
              </LinearGradientBrush>
            </Setter.Value>
          </Setter>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </TextBlock.Style>
</TextBlock>

和你的转换器:

public class ActiveProjectCheckConverter : IMultiValueConverter {
  public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
    string first = values[0] as string;
    string second = values[1] as string;
    return !string.IsNullOrEmpty(first) && !string.IsNullOrEmpty(second) && first == second;
  }

  public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
    throw new NotImplementedException();
  }
}

现在我确实在ViewModel中再做了一次更改,你的Project对象,如果你想要改变那些,你需要在View中反映你需要实现INPC本身。所以我确实更新了它,并将其重命名为ActiveProject

private Project _activeProject;

public Project ActiveProject {
  get {
    return _activeProject;
  }
  set {
    if (value == _activeProject)
      return;
    _activeProject = value;
    RaisePropertyChanged(() => ActiveProject);
  }
}

<强>更新

您可以在Dropbox-Link

找到上述更新