【问题标题】:Using image in bool-type column when using AutoGenerateColumn (WPF)使用 AutoGenerateColumn (WPF) 时在布尔型列中使用图像
【发布时间】:2013-12-05 07:49:27
【问题描述】:

我有

if (e.PropertyType == typeof(bool))
        {             
           e.Column.Header = "Status";
           DataGridTemplateColumn templateColumn = new DataGridTemplateColumn();
           templateColumn.Header = "Status";
           DataTemplate imageTemplate = new DataTemplate();

           DataTrigger imageBoolTrigger = new DataTrigger();
           Converter.BoolToImage boolToImage = new Converter.BoolToImage();

           Uri trueImageURI = new Uri(@"pack://application:,,,/MonitorView_wpf;component/Images/Icons/check-mark-16.png", UriKind.RelativeOrAbsolute);

           boolToImage.TrueImage.Source = new BitmapImage(trueImageURI);

           imageBoolTrigger.Binding = new Binding { Converter = boolToImage, ConverterParameter = e.Column };

           imageTemplate.Triggers.Add(imageBoolTrigger);
           templateColumn.CellTemplate = imageTemplate;

           e.Column = templateColumn;

        }

但是很可惜,它不起作用。

如何使用图像而不是自动生成的复选框?

我的转换器如下所示:

 public class BoolToImage : IValueConverter
    {
        public Image TrueImage { get; set; }
        public Image 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();
        }
    }

我的图像确实存在于程序集中,它是一个 png - 我尝试了各种方法,但都没有工作。

提前致谢

【问题讨论】:

    标签: wpf autogeneratecolumn


    【解决方案1】:

    我喜欢的后台代码太多了,我个人会在资源中为它创建一个模板:

        <DataGridTemplateColumn x:Key="booleanImageTemplate">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Image Name="theImage" Width="64" Height="64" Source="true_image.png"/>
                    <DataTemplate.Triggers>
                        <DataTrigger Binding="{Binding theBooleanPropertyName}" Value="False">
                            <Setter TargetName="theImage" Property="Source" Value="false_image.png"/>
                        </DataTrigger>
                    </DataTemplate.Triggers>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    

    然后在创建时覆盖它:

    <Grid>
        <DataGrid AutoGenerateColumns="True" ItemsSource="{Binding}" AutoGeneratingColumn="OnAutogeneratingColumn" />
    </Grid>
    
    private void OnAutogeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
        {
            if (e.Column.Header.ToString() == "theBooleanPropertyName")
                e.Column = (DataGridTemplateColumn)Resources["booleanImageTemplate"];
        }
    

    我刚刚在这里使用了一张图片(有效地使该列成为只读),但它与模板复选框同样适用。

    【讨论】:

      【解决方案2】:

      您是否尝试在转换器中放置断点并查看该代码是否实际运行? 也许,在代码中创建 DataTemplate 的更好方法是使用 FrameworkElementFactory,所以下面的代码应该可以工作:-

       if (e.PropertyType == typeof(bool))
        { 
           DataTemplate imageTemplate= new DataTemplate();
      
           //set up the stack panel
           FrameworkElementFactory imageFactory = new FrameworkElementFactory(typeof(Image));
      
           Converter.BoolToImage boolToImage = new Converter.BoolToImage();
           Uri trueImageURI = new Uri   (@"pack://application:,,,/MonitorView_wpf;component/Images/Icons/check-mark-16.png",  UriKind.RelativeOrAbsolute);
           boolToImage.TrueImage.Source = new BitmapImage(trueImageURI);
           var binding= new Binding { Converter = boolToImage, ConverterParameter = e.Column };
            imageFactory.SetBinding(Image.SOurceProperty,binding);
      
            //set the visual tree of the data template
            imageTemplate.VisualTree = imageFactory ;
      
            var templateColumn = new DataGridTemplateColumn();
            templateColumn.Header = "Status";
            templateColumn.CellTemplate=imageTemplate;
            e.Column=templateColumn;
           }
      

      您还可以使用“XamlReader”在代码中创建模板。

      以下代码使用 XamlReader 在代码中创建 DataTemplate 并将其分配给 CellTemplate。

       var templateColumn = new DataGridTemplateColumn();
       templateColumn.Header = "Status";
      
       templateColumn.CellTemplate = XamlReader.Parse(GetDataTemplate()) as DataTemplate;
       e.Column = templateColumn;
      
       public string GetDataTemplate()
          {
      
              var dt = @"<DataTemplate x:Key=""dt"" xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
          xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
          <Canvas>
             <Ellipse
        Canvas.Top=""5""
        Canvas.Left=""5""
        Fill=""#FFFFFF00""
        Height=""10""
        Width=""10""
        StrokeThickness=""5""
        Stroke=""#FF0000FF""/>
          </Canvas>
          </DataTemplate>";
              return dt;
          }
      

      请注意,这使用带有椭圆的画布,但您可以轻松放置路径。

      【讨论】:

      • 我可以用 Canvas 代替 png 吗?如何?我实际上更喜欢使用画布(我有作为资源(moderuicons.com))我会怎么做?我目前的错误是 New BitMapImage(trueImageURI);
      • 抱歉,您能详细说明一下吗?您想使用“画布”而不是图像吗?你想从网上加载图片还是什么?
      • 我有一个资源——它是一个画布,带有一个绘制的路径(一个图标)——我可以用它代替 png 吗?——我将如何使用该资源而不是实际图像? --- 我的 png 似乎得到了一个空引用 - 我想知道 png 是否有问题。
      • 下面的代码使用XamlReader在代码中创建DataTemplate并赋值给CellTemplate。
      【解决方案3】:

      如果我的理解是正确的,我建议你将 AutoGenerateColumns 设置为 false。

      并使用将布尔值转换为所需图像的转换器。 这是我项目中的一个类似示例。 不过,我没有使用图像,而是根据绑定的布尔值更改了背景颜色。

      <DataGridTemplateColumn Header="5_5" MaxWidth="10">
                          <DataGridTemplateColumn.CellTemplate>
                              <DataTemplate>
                                  <Textblock Background="{Binding _booleanValue, Converter={StaticResource  ResourceKey=hourSlotColorConverter}, 
                                              UpdateSourceTrigger=PropertyChanged}"/>
                              </DataTemplate>
                          </DataGridTemplateColumn.CellTemplate>
                      </DataGridTemplateColumn>
      

      这就是我的转换器的样子:

      class HourSlotToBrushConverter : IValueConverter
          {
              public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
              {
                  // if value isn't null, we can safely do the conversion. 
                  if (value != null)
                  {
                      if ((bool)value)
                          return Brushes.LimeGreen;
                  }
      
                  return Brushes.White;
              }
      
              public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
              {
                  throw new NotImplementedException();
              }
          }
      

      我希望这会有所帮助。

      【讨论】:

      • 不可能自动生成为 false
      • 您能详细说明一下吗?您在数据网格中使用了多少列?
      • 动态量 - 由最终用户生成 - 我将其设计为自动生成真实
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-24
      • 2021-07-31
      • 2011-08-01
      • 1970-01-01
      • 2011-05-03
      • 1970-01-01
      • 2019-04-03
      相关资源
      最近更新 更多