使用IValueConverter在多个dataGrid单元格中显示相同的xaml格式图像

时间:2016-04-29 08:41:37

标签: wpf xaml

我有一个可行的解决方案,使用<Viewbox>将布尔值转换为<ContentControl>内的xaml-image,如下所示:

<DataGridTemplateColumn>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ContentControl Content="{Binding Recommended, Converter={StaticResource BoolImageConverter}}" Height="20"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

但是使用上述解决方案,转换的图像仅显示在第一个单元格中。

  

如何正确使用<ControlTemplate><Control>   情况?

I have looked into this answer但我无法使用Converter重现有效的解决方案。

xaml-image

的示例
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Viewbox x:Key="Symbols.StarIcon">
        <Canvas Width="46" Height="44" >
           ...
        </Canvas>
    </Viewbox>
</ResourceDictionary>

转换器的想法来自this post

public class BoolToImage : IValueConverter
{
    public Viewbox TrueImage { get; set; }
    public Viewbox FalseImage { get; set; }

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (!(value is bool))
        {
            return null;
        }

        bool b = (bool)value;
        if (b)
        {
            return this.TrueImage;
        }
        else
        {
            return this.FalseImage;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

2 个答案:

答案 0 :(得分:1)

您的ViewBox是一个带密钥的控件。并且控件只能有一个可视父级。因此,第一个单元格垄断了ViewBox,而其他单元格则无法使用它。

在您的情况下,最好使用CellTemplateSelector属性。 首先,创建自定义DataTemplateSelector:

public class TrueFalseSelector : DataTemplateSelector
{
   public DataTemplate TrueTemplate { get; set; }
   public DataTemplate FalseTemplate { get; set; }

   public override DataTemplate SelectTemplate(object item, DependencyObject container)
   {
      if (item == null) return null;

      var isSomething = ((CustomObjectType) item).CustomBoolProperty;
      return isSomething ? this.TrueTemplate
                         : FalseTemplate;
   }
}

然后在XAML中使用它。在资源中的某处添加选择器:

 <local:TrueFalseSelector x:Key="trueFalseSelector">
      <local:TrueFalseSelector.TrueTemplate>
          <DataTemplate>
              <!-- your true template here -->
          </DataTemplate>
      </local:TrueFalseSelector.TrueTemplate>
      <local:TrueFalseSelector.FalseTemplate>
          <DataTemplate>
              <!-- your false template here -->
          </DataTemplate>
      </local:TrueFalseSelector.FalseTemplate>
 </local:TrueFalseSelector>

瞧:

 <DataGrid.Columns>
      <DataGridTemplateColumn CellTemplateSelector="{StaticResource trueFalseSelector}" />
 </DataGrid.Columns>

编辑:您可以将DataTemplates放在ViewBox所在的同一个字典中。给他们一把钥匙,就这样使用:

<local:TrueFalseSelector x:Key="trueFalseSelector"
                         FalseTemplate="{StaticResource falseTemplate}"
                         TrueTemplate="{StaticResource trueTemplate">

答案 1 :(得分:1)

这是你可以做到的另一种方式(纯xaml):

<DataGridTemplateColumn>
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <ContentControl Style="{StaticResource RecommendedStyle}"/>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>  
    <Style TargetType="ContentControl" x:Key="RecommendedStyle">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <ViewBox x:Key="True"/>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
    <Style.Triggers>
        <DataTrigger Binding="{Binding Recommended}" Value="False">
            <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <ViewBox x:Key="False"/><!--This is image for false-->
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
        </DataTrigger>
    </Style>