Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic binding to a "Path" of the resource

First the code what I was starting from:

<ribbon:RibbonMenuButton IsEnabled="{Binding ForegroundIsConfigurable}"
          SmallImageSource="{Binding Source={StaticResource imageSource},
                             Path=Source,
                             UpdateSourceTrigger=OnPropertyChanged}">

While this binding is compiling and running fine the reason I am not satisfied is that imageSource changes during runtime.

StaticResource Markup Extension: Provides a value for any XAML property attribute by looking up a reference to an already defined resource. Lookup behavior for that resource is analogous to load-time lookup, which will look for resources that were previously loaded from the markup of the current XAML page as well as other application sources, and will generate that resource value as the property value in the run-time objects.

Since imageSource value changing during runtime I had to change StaticResource to DynamicResource. But the property Source is not a dependency property and thus the following code will raise a runtime error:

SmallImageSource="{Binding Source={DynamicResource imageSource},
                   Path=Source,
                   UpdateSourceTrigger=LostFocus}

For that reason I need to bind the dynamic resource directly to SmallImageSource, which is a dependency property:

SmallImageSource="{DynamicResource imageSource}"

This again will raise a runtime error because imageSource is type of Image. SmallImageSource expects the value to be type of ImageSource.

One might suggest now to set the data context to my dynamic resource and bind the property appropriately. If I do so, I'd kill the binding of property IsEnabled which has another DataContext.

And as far as I know, MultiBinding is also not a solution since this provides a mechanism to bind a property against several sources but does not provide binding different properties against different contexts and sources.

While thinking about how to get on, it came to my mind that luckily I can move the ImageSource rigmarole into a IValueConverter. In the given data context of my RibbonMenuButton I have a string value with the appropriate value which is actually also the source of my ImageSource.

Anyway, I still wondering how I would solve the problem if I hadn't the other approach, i.e. if both sources were in different data contexts. Is there anything what I am not seeing? How can I ensure not to kill the other binding by overwriting the DataContext and though binding against a property of a dynamic resource?


The imageSource is pretty the same as the XAML example on the DrawingImage msdn page.

<Image x:Key="imageSource">
  <Image.Source>
    <DrawingImage>
...
like image 284
Em1 Avatar asked Mar 26 '13 09:03

Em1


1 Answers

You might try defining "imageResource" as an ImageSource instead of an Image. This works for me.

<r:RibbonWindow
    x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:r="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
    xmlns:pc="clr-namespace:System.Windows.Media;assembly=PresentationCore">
    <Grid>
        <Grid.Resources>
            <pc:ImageSource x:Key="imageSource">your_image.png</pc:ImageSource>
        </Grid.Resources>
        <r:Ribbon>
            <r:RibbonMenuButton
                IsEnabled="{Binding ForegroundIsConfigurable}"
                SmallImageSource="{DynamicResource imageSource}">
            </r:RibbonMenuButton>
        </r:Ribbon>
    </Grid>
</r:RibbonWindow>

Also, you could set the DataContext of your RibbonMenuButton without overriding IsEnabled by using an ElementName binding as follows.

<r:RibbonWindow x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:r="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
        Title="MainWindow" Height="350" Width="525">

    <Grid x:Name="root">

        <Grid.Resources>
            <Image x:Key="imageSource" Source="{Binding myImageSource}"/>
        </Grid.Resources>

        <r:Ribbon>
            <r:RibbonMenuButton DataContext="{DynamicResource imageSource}"
                IsEnabled="{Binding ElementName=Root, Path=DataContext.ForegroundIsConfigurable}"
                SmallImageSource="{Binding Source}"/>
        </r:Ribbon>
    </Grid>
</r:RibbonWindow>
like image 183
Timothy Schoonover Avatar answered Oct 13 '22 00:10

Timothy Schoonover