3

我创建了这个DataTemplate,但我不知道如何将 astyle与 a添加DataTriggerimg变量中。

我希望img根据Suppliers[i].Stock(int)的值显示不同的图像

资源图标

Properties.Resources.InStock     => Suppliers[i].Stock > 0
Properties.Resources.OutOfStock  => Suppliers[i].Stock = 0
Properties.Resources.Unknown     => Suppliers[i].Stock = null

到目前为止我的代码。

private DataTemplate GetStockTemplate(int i)
{
    var template = new DataTemplate();

    var wp = new FrameworkElementFactory(typeof (WrapPanel));
    wp.SetValue(FrameworkElement.HorizontalAlignmentProperty, HorizontalAlignment.Right);
    wp.SetValue(WrapPanel.OrientationProperty, Orientation.Horizontal);

    var tx = new FrameworkElementFactory(typeof (TextBox));
    tx.SetBinding(TextBox.TextProperty, new Binding("Suppliers[" + i + "].Stock") {StringFormat = "{0:n0}"});
    tx.SetValue(TextBoxBase.IsReadOnlyProperty, true);
    tx.SetValue(Control.BorderThicknessProperty, new Thickness(0));
    tx.SetValue(Control.BackgroundProperty, Brushes.Transparent);
    tx.SetValue(TextBox.TextAlignmentProperty, TextAlignment.Right);

    wp.AppendChild(tx);

    var img = new FrameworkElementFactory(typeof (Image));
    wp.AppendChild(img);

    template.VisualTree = wp;
    template.Seal();
    return template;
}

我认为触发器可以工作的方式是,创建一个显示 InStock 图标的默认样式,然后在 forStock = null和另一个 for上设置两个触发器Stock = 0

由于我是动态执行此操作的,因此我无法使用 xaml,并且其他所有内容都可以使用DataTemplate.

解决方案

在@akjoshi 的帮助下,这就是我最终使用的。

var img = new FrameworkElementFactory(typeof(Image));
            var binding = new Binding("Suppliers[" + i + "].Stock") {Converter = new StockIconConverter()};
img.SetBinding(Image.SourceProperty, binding);
wp.AppendChild(img); 

class StockIconConverter :IValueConverter 
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null || (int)value < 0)
            return ConvertIconToBitmapImage(Properties.Resources.Unknown);

        return ConvertIconToBitmapImage((int)value == 0 ? Properties.Resources.OutOfStock : Properties.Resources.InStock);
    }

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

    #region Helper
    private static BitmapImage ConvertIconToBitmapImage(Icon icon)
    {
        var bitmap = icon.ToBitmap();
        var ms = new MemoryStream();
        bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        var bImg = new BitmapImage();

        bImg.BeginInit();
        bImg.StreamSource = new MemoryStream(ms.ToArray());
        bImg.CreateOptions = BitmapCreateOptions.None;
        bImg.CacheOption = BitmapCacheOption.Default;
        bImg.EndInit();
        bImg.Freeze();

        ms.Close();

        return bImg;
    }
    #endregion
}
4

1 回答 1

5

我认为您的想法是正确的,代码应该是这样的-

var img = new FrameworkElementFactory(typeof(Image)); 
img.SetValue(Image.SourceProperty, "InStockImagePath");

Style style = new Style();
style.TargetType = typeof(Image);

DataTrigger zeroDataTrigger = new DataTrigger();
zeroDataTrigger.Binding = new Binding("Suppliers[" + i + "].Stock");
zeroDataTrigger.Value = 0;
zeroDataTrigger.Setters.Add(new Setter(Image.SourceProperty, "OutOfStockImagePath"));

DataTrigger nullDataTrigger = new DataTrigger();
nullDataTrigger.Binding = new Binding("Suppliers[" + i + "].Stock");
nullDataTrigger.Value = null;
nullDataTrigger.Setters.Add(new Setter(Image.SourceProperty, "unknownImagePath"));

style.Triggers.Add(zeroDataTrigger);
style.Triggers.Add(nullDataTrigger);

img.SetValue(Image.StyleProperty, style);
wp.AppendChild(img); 

我建议您看一下 Sacha 的以下与此相关的精彩文章 -

WPF:如何在代码/和神奇的内容中创建样式

作为旁注,就像FrameworkElementFactorydeprecated一样,最好在其中定义此样式Resources/xaml并用于FindResource()设置它。如果一些重新设计可以使您实现这一目标,那么我建议您这样做。

于 2012-07-17T09:47:23.883 回答