2012-07-17 56 views
2

我创造了这个DataTemplate,但我无法弄清楚如何使用DataTrigger添加styleIMG变量。的DataTemplate的风格和DateTriggers从代码

我想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图标默认样式,然后有对Stock = null两个触发器,另一个用于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 
} 
+0

很高兴帮助; +1发布答案。 – akjoshi 2012-07-17 12:02:09

+0

一个建议是,你可以为一个图标创建一个'BitmapImage'并将其缓存到转换器本身中,然后使用它来代替一次又一次地创建它,否则最终会创建相同的BitmapImage'n'次并降低性能。 – akjoshi 2012-07-17 12:02:23

回答

3

我认为你的想法是对的,代码应该是这样的 -

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); 

,我建议你看看下面的萨沙大文章,与此相关的 -

WPF: How to create Styles in code/and magical Content

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

+1

是的,我应该找时间将代码重写到xaml中,因为它比使用xaml更加努力地使用FrameworkElementFactory,并且几乎没有文档。 – gulbaek 2012-07-17 10:05:09

+0

嗯,DataTrigger没有开火。股票发送和PropertyChanged事件。 – gulbaek 2012-07-17 10:17:23

+0

@gulbaek很难说最新的错误,只要确保图像路径正确URl和绑定源也存在于DataContext中;你也可以尝试添加一个转换器到触发器绑定,看看它是否被触发,而不是它的值是什么。 – akjoshi 2012-07-17 10:33:32