简体   繁体   中英

How to modify Image Source in WPF XAML dynamically

I have a WPF App that has (so far) 2 modes of display, regularmode and widgetmode.

I am using Prism 6 with MVVM design pattern.

MainWindowViewModel knows the mode of display.

ToolBarView has, as expected, a toolbar of buttons and the buttons shall be dynamically changed to different images depending on the mode of the view. If the mode is WidgetMode, it switches to the image with an identical name but with an '_w' added. So instead of "image.png", it's "image_w.png".

What I'd like to do is create a string in ToolBarView that is updated to either String.Empty or to "_w", depending on the mode. I'd also like the image root folder to be a global string, rather than a hardcoded string, so I have defined that in app.xaml.

<Application.Resources>

    <sys:String x:Key="ImageURIRoot">/MyApp;component/media/images/</sys:String>
</Application.Resources>

Then in my toolbarview (a usercontrol), I did this:

<UserControl.Resources>
    <converters:StringToSourceConverter x:Key="strToSrcConvert"/>

    <sys:String x:Key="BtnImgSuffix">_w</sys:String>
.
.
.
</UserControl.Resources>

Note that the string is hardcoded; eventually, I will change it dynamically based off the windowmode.

I then put the Buttons in a Listbox

<ListBoxItem Style="{StaticResource MainButton_Container}">
                <Button Command="{Binding ButtonActionDelegateCommand}" Style="{StaticResource Main_Button}">
                    <Image Source="{Binding Source={StaticResource ImageURIRoot}, Converter={StaticResource strToSrcConvert}, ConverterParameter='{}{0}button.png'}" />
                </Button>
            </ListBoxItem>

Converter code:

public class StringToSourceConverter : IValueConverter
{


    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (parameter is string)
        {
            return string.Format(parameter.ToString(), value);
        }
        return null;
    }

    public object ConvertBack(object value, Type targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }
}

So that works. But what I want is to have the ConverterParameter equal "{}{0}button{1}.png", where {0} is the URI Root and {1} is the suffix. But I can't figure out how to do it. I know it's simple, but I can't put my finger on it!

Please help!

Figured it out and it was through multibinding. The way I did it was create a converter that inherits from IMultiValueConverter. Its "Convert" method looks like this:

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{


    ImageSourceConverter conv = new ImageSourceConverter();

    int suffixPos = ((String)parameter).Length - 4;
    var returnValue = ((String)parameter).Insert(suffixPos, values[1].ToString());

    returnValue = Path.Combine(values[0].ToString(), returnValue);  

    ImageSource imgsrc = conv.ConvertFromString(returnValue) as ImageSource;

    return imgsrc;               

}

The xaml looks like this:

<Image  Height="30" Width="40" diag:PresentationTraceSources.TraceLevel="High">
    <Image.Source>
        <MultiBinding Converter="{StaticResource stringsToSrcConvert}" ConverterParameter="buttonImg.png">
            <Binding Source="{StaticResource ImageURIRoot}"/>
            <Binding Source="{StaticResource BtnImgSuffix}"/>
        </MultiBinding>
    </Image.Source>
</Image>   

Also, had to modify the URIRoot

<Application.Resources>        
    <sys:String x:Key="ImageURIRoot">pack://application:,,,/MyApp;component/media/images/</sys:String>
</Application.Resources>

Thanks, Clemens!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM