WPF的ImageSource使用自定义转换器的结合自定义、转换器、WPF、ImageSource

2023-09-03 13:35:09 作者:夜已尽、殇未央

我有一个结构化的这样一个组合框一个简单的模板:

 <组合框DockPanel.Dock =左了minWidth =100了maxHeight =24
          的ItemsSource ={结合操作}>
    < ComboBox.ItemTemplate>
        <的DataTemplate>
            < StackPanel的方向=横向>
                < TextBlock的文本={结合名}WIDTH =100/>
                <图像源={结合转换器= {的StaticResource类型转换器}}/>
            < / StackPanel的>
        < / DataTemplate中>
    < /ComboBox.ItemTemplate>
< /组合框>
 

所以,如果我用这个code,一切正常:

 < TextBlock的文本={结合名}WIDTH =100/>
<! - <图像源={结合转换器= {的StaticResource类型转换器}}/> - >
<图像源={的StaticResource SecurityImage}/>
 

但是,如果我使用转换器不工作了。 这是转换器,但我不知道我可以指静态资源从那里......

 公共对象转换(对象的值,类型TARGETTYPE,对象参数,CultureInfo的文化)
{
    VAR型=(动作)值;
    VAR IMG =新的BitmapImage();
    开关(type.ActionType)
    {
        案例ActionType.Security:
            img.UriSource =新的URI(StructureImage,UriKind.Relative);
            打破;
        案例ActionType.Structural:
            img.UriSource =新的URI(SecurityImage,UriKind.Relative);
            打破;
    }

    返回IMG;
}
 
WPF 精修篇 值转换器

解决方案

尝试使用开关转换器写的乔希,应该为你工作:

SwitchConverter -

  

一个switch语句的XAML -   的http://josheinstein.com/blog/index.php/2010/06/switchconverter-a-switch-statement-for-xaml/

没有必要写你的转换器,你的code看起来像这样 -

 < Grid.Resources>
    < E:SwitchConverter X:关键=ActionIcons>
        < E:SwitchCase当=安全然后=SecurithImage.png/>
        < E:SwitchCase当=结构性然后=StructureImage.png/>
    < / E:SwitchConverter>
< /Grid.Resources>

<图像源={结合转换器= {的StaticResource ActionIcons}}/>
 

编辑:

下面是$ C $ SwitchConverter了C作为 Josh的网站似乎是下降 -

  ///<总结>
/// A转换器,它接受和LT;见CREF =SwitchConverterCase/> S,并将其转换为
///接着的情况下的特性。
///< /总结>
[ContentProperty(案例)
公共类SwitchConverter:的IValueConverter
{
    //转换器实例。
    名单< SwitchConverterCase> _cases;

    #地区的公共属性。
    ///<总结>
    ///获取或设置℃的阵列;见CREF =SwitchConverterCase/> S,该转换器可用于从produde值。
    ///< /总结>
    公开名单< SwitchConverterCase>案例{{返回_cases; }集合{_cases =价值; }}
    #endregion
    #地区的建设。
    ///<总结>
    ///初始化的新实例的<看到CREF =SwitchConverter/>类。
    ///< /总结>
    公共SwitchConverter()
    {
        //创建的情况下阵列。
        _cases =新的名单,其中,SwitchConverterCase>();
    }
    #endregion

    ///<总结>
    ///一个值转换。
    ///< /总结>
    ///<参数名称=值>通过绑定源产生的值小于/参数>
    ///< PARAM NAME =TARGETTYPE>将结合目标属性的类型< /参数>
    ///&所述; PARAM NAME =参数>将转换器参数使用< /参数>
    ///< PARAM NAME =文化>文化在转换器使用< /参数>
    ///<返回>
    ///一个转换后的值。如果该方法返回null,有效的空值。
    ///< /回报>
    公共对象转换(对象的值,类型TARGETTYPE,对象参数,System.Globalization.CultureInfo文化)
    {
        //这将是该操作的结果。
        对象的结果= NULL;

        //我只愿意SwitchConverterCases转换在该转换器,也没有空!
        如果(价值== NULL)抛出新ArgumentNullException(价值);

        //我需要找出是否匹配该值的情况下确实存在这种转换器的情况下收集。
        如果(_cases =空&安培;!&安培; _cases.Count大于0)
            的for(int i = 0; I< _cases.Count;我++)
            {
                //获取一个参考这种情况。
                SwitchConverterCase targetCase = _cases [I]

                //检查,看看是否值为情况下,当参数。
                如果(价值== targetCase || value.ToString()。ToUpper的()== targetCase.When.ToString()。ToUpper的())
                {
                    //我们已经得到了我们想要的东西,结果现在可以设置为当时的财产
                    //的情况下我们的。
                    结果= targetCase.Then;

                    //全部完成,走出循环。
                    打破;
                }
            }

        //返回结果。
        返回结果;
    }

    ///<总结>
    ///一个值转换。
    ///< /总结>
    ///&所述; PARAM NAME =值>由所述结合靶产生的值小于; /参数>
    ///< PARAM NAME =TARGETTYPE>到转换为类型< /参数>
    ///&所述; PARAM NAME =参数>将转换器参数使用< /参数>
    ///< PARAM NAME =文化>文化在转换器使用< /参数>
    ///<返回>
    ///一个转换后的值。如果该方法返回null,有效的空值。
    ///< /回报>
    公共对象ConvertBack(对象的值,类型TARGETTYPE,对象参数,System.Globalization.CultureInfo文化)
    {
        抛出新的NotImplementedException();
    }
}

///<总结>
///重新presents用于开关变换器的情况。
///< /总结>
[ContentProperty(然后)
公共类SwitchConverterCase
{
    //例实例。
    串_when;
    对象_then;

    #地区的公共属性。
    ///<总结>
    ///获取或设置的情况下的状态。
    ///< /总结>
    公共字符串当{{返回_when; }集合{_when =价值; }}
    ///<总结>
    ///获取或设置通过&LT运行时,这种情况下的结果;看到CREF =SwitchConverter/>
    ///< /总结>
    公共对象,然后{{返回_then; }集合{_then =价值; }}
    #endregion
    #地区的建设。
    ///<总结>
    ///开关转换器。
    ///< /总结>
    公共SwitchConverterCase()
    {
    }
    ///<总结>
    ///初始化℃的新的实例;参见CREF =SwitchConverterCase/>类。
    ///< /总结>
    ///< PARAM NAME =当与GT;的情况下的条件和LT; /参数>
    ///< PARAM NAME =,然后>将这种情况下,通过运行时的结果<见CREF =SwitchConverter/>< /参数>
    公共SwitchConverterCase(字符串时,对象则)
    {
        //挂接实例。
        this._then =即可;
        this._when时=;
    }
    #endregion

    ///<总结>
    ///返回一个<见CREF =System.String/>那些重新presents此实例。
    ///< /总结>
    ///<返回>
    /// A<见CREF =System.String/>那些重新presents此实例。
    ///< /回报>
    公共重写字符串的ToString()
    {
        返回的String.Format(当= {0};然后= {1},When.ToString(),Then.ToString());
    }
}
 

更新:

另一个SwitchConverter 实现从微软引用源。

I have a simple template for a combobox structured in this way:

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

So, if I use this code, everything works:

<TextBlock Text="{Binding Name}" Width="100" />
<!--<Image Source="{Binding Converter={StaticResource TypeConverter}}" /> -->
<Image Source="{StaticResource SecurityImage}" />

But if I use the converter it doesn't work anymore. This is the converter, but I don't know how I can refer to the static resource from there ...

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

解决方案

Try to use the Switch Converter written by Josh, should work for you:

SwitchConverter –

A "switch statement" for XAML - http://josheinstein.com/blog/index.php/2010/06/switchconverter-a-switch-statement-for-xaml/

No need to write your converter, your code will look like this -

<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}}" />  

EDIT:

Here is code of SwitchConverter as Josh's site seems to be down -

/// <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());
    }
}

Update:

Another SwitchConverter implementation from Microsoft Reference Source.