Dot-Net
WPF ImageSource 與自定義轉換器綁定
我有一個以這種方式構造的組合框的簡單模板:
<ComboBox DockPanel.Dock="Left" MinWidth="100" MaxHeight="24" ItemsSource="{Binding Actions}"> <ComboBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Name}" Width="100" /> <Image Source="{Binding Converter={StaticResource TypeConverter}}" /> </StackPanel> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox>所以,如果我使用這段程式碼,一切正常:
<TextBlock Text="{Binding Name}" Width="100" /> <!--<Image Source="{Binding Converter={StaticResource TypeConverter}}" /> --> <Image Source="{StaticResource SecurityImage}" />但是,如果我使用轉換器,它就不再起作用了。這是轉換器,但我不知道如何從那裡引用靜態資源……
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var type = (Action)value; var img = new BitmapImage(); switch (type.ActionType) { case ActionType.Security: img.UriSource = new Uri("StructureImage", UriKind.Relative); break; case ActionType.Structural: img.UriSource = new Uri("SecurityImage", UriKind.Relative); break; } return img; }
嘗試使用 Josh 編寫的 Switch Converter,應該對您有用:
開關轉換器 –
XAML 的“開關語句” - http://josheinstein.com/blog/index.php/2010/06/switchconverter-a-switch-statement-for-xaml/
無需編寫轉換器,您的程式碼將如下所示 -
<Grid.Resources> <e:SwitchConverter x:Key="ActionIcons"> <e:SwitchCase When="Security" Then="SecurithImage.png" /> <e:SwitchCase When="Structural" Then="StructureImage.png" /> </e:SwitchConverter> </Grid.Resources> <Image Source="{Binding Converter={StaticResource ActionIcons}}" />更新1:
這是 SwitchConverter 的程式碼,因為Josh 的網站似乎已關閉 -
/// <summary> /// A converter that accepts <see cref="SwitchConverterCase"/>s and converts them to the /// Then property of the case. /// </summary> [ContentProperty("Cases")] public class SwitchConverter : IValueConverter { // Converter instances. List<SwitchConverterCase> _cases; #region Public Properties. /// <summary> /// Gets or sets an array of <see cref="SwitchConverterCase"/>s that this converter can use to produde values from. /// </summary> public List<SwitchConverterCase> Cases { get { return _cases; } set { _cases = value; } } #endregion #region Construction. /// <summary> /// Initializes a new instance of the <see cref="SwitchConverter"/> class. /// </summary> public SwitchConverter() { // Create the cases array. _cases = new List<SwitchConverterCase>(); } #endregion /// <summary> /// Converts a value. /// </summary> /// <param name="value">The value produced by the binding source.</param> /// <param name="targetType">The type of the binding target property.</param> /// <param name="parameter">The converter parameter to use.</param> /// <param name="culture">The culture to use in the converter.</param> /// <returns> /// A converted value. If the method returns null, the valid null value is used. /// </returns> public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { // This will be the results of the operation. object results = null; // I'm only willing to convert SwitchConverterCases in this converter and no nulls! if (value == null) throw new ArgumentNullException("value"); // I need to find out if the case that matches this value actually exists in this converters cases collection. if (_cases != null && _cases.Count > 0) for (int i = 0; i < _cases.Count; i++) { // Get a reference to this case. SwitchConverterCase targetCase = _cases[i]; // Check to see if the value is the cases When parameter. if (value == targetCase || value.ToString().ToUpper() == targetCase.When.ToString().ToUpper()) { // We've got what we want, the results can now be set to the Then property // of the case we're on. results = targetCase.Then; // All done, get out of the loop. break; } } // return the results. return results; } /// <summary> /// Converts a value. /// </summary> /// <param name="value">The value that is produced by the binding target.</param> /// <param name="targetType">The type to convert to.</param> /// <param name="parameter">The converter parameter to use.</param> /// <param name="culture">The culture to use in the converter.</param> /// <returns> /// A converted value. If the method returns null, the valid null value is used. /// </returns> public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } } /// <summary> /// Represents a case for a switch converter. /// </summary> [ContentProperty("Then")] public class SwitchConverterCase { // case instances. string _when; object _then; #region Public Properties. /// <summary> /// Gets or sets the condition of the case. /// </summary> public string When { get { return _when; } set { _when = value; } } /// <summary> /// Gets or sets the results of this case when run through a <see cref="SwitchConverter"/> /// </summary> public object Then { get { return _then; } set { _then = value; } } #endregion #region Construction. /// <summary> /// Switches the converter. /// </summary> public SwitchConverterCase() { } /// <summary> /// Initializes a new instance of the <see cref="SwitchConverterCase"/> class. /// </summary> /// <param name="when">The condition of the case.</param> /// <param name="then">The results of this case when run through a <see cref="SwitchConverter"/>.</param> public SwitchConverterCase(string when, object then) { // Hook up the instances. this._then = then; this._when = when; } #endregion /// <summary> /// Returns a <see cref="System.String"/> that represents this instance. /// </summary> /// <returns> /// A <see cref="System.String"/> that represents this instance. /// </returns> public override string ToString() { return string.Format("When={0}; Then={1}", When.ToString(), Then.ToString()); } }更新2: