tags:

views:

189

answers:

1

I am trying to develop an application that uses a number of images that are stored in a seperate remote file location. The file-paths to the UI elements are stored within the Application Settings. Although I understand how to access and use the file-path from Settings in C# (Properties.Settings.Default.pathToGridImages + "OK.png"), I am at a loss to figure out how to utilize the Settings paths in WPF, and can only seem to access the file if I include the file-path, such as:

<Grid.Background>
     <ImageBrush ImageSource="C:\Skins\bottomfill.png" TileMode="Tile" />
</Grid.Background>

I would have thought that concatenating "Properties.Settings.Default.pathToGridImages" with "bottomfill.png" in WPF could be done much like it can be done in C#. Can anyone please point me in the right direction?

+1  A: 

You can do this using a MultiBinding and a value converter. To start with, use a multibinding to bind your image source to the base path, and the image name:

<ImageBrush>
    <ImageBrush.ImageSource>
        <MultiBinding Converter="{StaticResource MyConverter}">
            <Binding Source="{StaticResource MySettings}" Path="Default.FilePath" />
            <Binding Source="ImageName.png"></Binding>
        </MultiBinding>
    </ImageBrush.ImageSource>
</ImageBrush>

You then need to have a converter that implements IMultiValueConverter and combines the two parts of the path and creates the image using either an ImageSourceConverter or by creating a new BitmapImage:

class MyConverter: IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        // Concatenate the values.
        string filename = Path.Combine(values[0].ToString(), values[1].ToString());

        // You can either use an ImageSourceConverter
        // to create your image source from the path.
        ImageSourceConverter imageConverter = new ImageSourceConverter();
        return imageConverter.ConvertFromString(filename);

        // ...or you can create a new bitmap with the combined path.
        return new BitmapImage(new Uri(filename, UriKind.RelativeOrAbsolute));
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        // No need to implement the convert back as this will never be used in two way binding.
        throw new NotImplementedException();
    }
}

Obviously, you need to declare namespaces and resource to the CLR stuff in the XAML so you can access it (If you've called your settings and converter classes something different, make sure you change this to match up):

...
xmlns:local ="clr-namespace:WpfApplication1">
<Window.Resources>
    <local:MyConverter x:Key="MyConverter"></local:MyConverter>
    <local:MySettings x:Key="MySettings"></local:MySettings>
</Window.Resources>

I've tested it out and it works fine.

[An alternative way would be just to bind the ImageSource property to a property on your data context that combined the paths in C# code, but that would depend on how you've got your datacontexts set up, so may be undesirable in many cases.]

Simon P Stevens
Simon Thank you very much for your help and advice. I wasn't certain how to utilize "MySettings" however (my inexperience) as I was storing the paths in the Application Settings (Settings.settings). I changed your Window.Resources "MySettings" suggestion slightly to <ObjectDataProvider x:Key="Properties.Settings" ObjectType="{x:Type local:Properties.Settings}" /> and it all worked like a charm. I do have another question, which I will post seperately and I'm hopeful you be kind enough to help me again. Thank you again.Bill
Bill
@Bill: No problem. Glad to help. Sure, if you post more questions I'll keep an look out for it and see if I can be any use. Your Settings.settings is basically the same thing, I'd just renamed the class "MySettings" instead of "Settings". No difference really.
Simon P Stevens