2012-07-17 27 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