基于两个视图模型的条件格式

时间:2017-02-02 09:34:17

标签: c# wpf xaml

有没有办法根据多个视图模型中的条件应用样式。

例如,我有一个项目列表,可以在项目级别有条件地格式化,但我也希望能够在整个列表级别打开或关闭格式:

主视图模型

class ParentViewModel : ViewModelBase
{
    public ParentViewModel ()
    {
        Items = new ObservableCollection<ChildViewModel> {
            new ChildViewModel{ Display = "I am red", Format=1 },
            new ChildViewModel{ Display = "I am red", Format=1 },
            new ChildViewModel{ Display = "I am blue", Format=2 },
            new ChildViewModel{ Display = "I am blue", Format=2 },
        };
        ShowFormatting = false;
    }

    public ObservableCollection<ChildViewModel> Items { get ... }

    // I would like to use this property to turn formatting off for the whole list
    public bool ShowFormatting { get ... } 
}

包含许多子视图模型

class ChildViewModel: ViewModelBase
{
    public string Display { get ... }

    public int Format { get ... }
}

在窗口中显示

<Window ...>
  <Grid>

    <Grid.Resources>
      <Style x:Key="MyStyle" TargetType="{x:Type TextBlock}">
        <Style.Triggers>
<!-- How can I access ShowFormatting from the main view model here? --> 
          <DataTrigger Binding="{Binding Format}" Value="1">
            <Setter Property="Foreground" Value="Red"></Setter>
          </DataTrigger>
          <DataTrigger Binding="{Binding Format}" Value="2">
            <Setter Property="Foreground" Value="Blue"></Setter>
          </DataTrigger>
        </Style.Triggers>
      </Style>
    </Grid.Resources>

    <ListView ItemsSource="{Binding Items}">
      <ListView.View>
        <GridView>
          <GridViewColumn>
            <GridViewColumn.CellTemplate>
<!-- Or can I apply the conditional formatting here? -->
              <DataTemplate DataType="{x:Type local:ChildViewModel}">
                <TextBlock Text="{Binding Display}" Style="{StaticResource MyStyle}"></TextBlock>
              </DataTemplate>
            </GridViewColumn.CellTemplate>
          </GridViewColumn>
        </GridView>
      </ListView.View>
    </ListView>

  </Grid>
</Window>

我看到的问题是该样式的目标是ChildViewModel,并且无法访问ShowFormatting属性。我能想出的最佳解决方案是从ChildViewModelParentViewModel的反向链接,但反向链接通常对我来说很糟糕。有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

如何使用RelativeSource进行绑定? (我假设您的Window的DataContext是ParentViewModel}

类型
<Grid.Resources>
  <Style x:Key="MyStyle" TargetType="{x:Type TextBlock}">
    <Style.Triggers>
      <DataTrigger Binding="{Binding Format}" Value="1">
        <Setter Property="Foreground" Value="Red"></Setter>
      </DataTrigger>
      <DataTrigger Binding="{Binding Format}" Value="2">
        <Setter Property="Foreground" Value="Blue"></Setter>
      </DataTrigger>
      <DataTrigger Binding="{Binding Path=DataContext.ShowFormatting, RelativeSource={RelativeSource AncestorType=Window}}" Value="SomeValue">
        <Setter Property="SomeProperty" Value="SetToThisValue"></Setter>
      </DataTrigger>
    </Style.Triggers>
  </Style>
</Grid.Resources>

答案 1 :(得分:1)

这样做的一种方法是拥有两个不同的子视图模型,ChildViewModel1ChildViewModel2ParentViewModel将使用以下一种或两种类型填充Items:如果您愿意,可以使用ObservableCollection<object>。为ChildViewModel1定义数据模板时,为ChildViewModel2定义另一个数据模板,然后根据ObservableCollection中的子视图模型,您将获得相应的渲染。