2

We have some XAML which may seem odd but apparently is needed for defining a couple of buttons inside a third party's ribbon gallery control. The gallery has a ItemsControl.ItemsSource which the XAML is populating with two Array items, these array items are a custom type which has a bitmap property and a ICommand property. Everything looks fine but I cannot get the array item property to bind to anything to do with the window's data context. I have tried every trick i know, RelativeSource, ElementName but to no avail. Below is the XAML:

<ribbon:RibbonGallery.ItemsSource>
    <x:Array Type="{x:Type customUITypes:ClickableImage}">
        <customUITypes:ClickableImage   x:Name="BitmapAddWorkflow" Command="{Binding ElementName=MainView, Path=DataContext.MyCommandOne}">
            <customUITypes:ClickableImage.Bitmap>
                <BitmapImage UriSource="/Images/GalleryWorkflowAdd.png"/>
            </customUITypes:ClickableImage.Bitmap>
        </customUITypes:ClickableImage>
        <customUITypes:ClickableImage  x:Name="BitmapDeleteWorkflow" Command="{Binding ElementName=MainView, Path=DataContext.MyCommandTwo}">
            <customUITypes:ClickableImage.Bitmap>
                <BitmapImage UriSource="/Images/GalleryWorkflowDelete.png"/>
            </customUITypes:ClickableImage.Bitmap>
        </customUITypes:ClickableImage>                                        
    </x:Array>
</ribbon:RibbonGallery.ItemsSource>
<ribbon:RibbonGallery.ItemTemplate>
    <DataTemplate>
        <Button Command="{Binding Command}">
           <Image Margin="2" Source="{Binding Bitmap}" Stretch="None"/>
        </Button>
    </DataTemplate>
</ribbon:RibbonGallery.ItemTemplate>

Note : MainView is the name of the window, the data context is 100% what I want, I have no problems with any other bindings on this view, just within this array definition.

I guess I'm getting in a muddle with regards to the hierarchy of the objects i have access to but in my opinion regardless of whether I'm binding inside the array definition markup i should still be able to find an element and bind to it's data context. Sometimes XAML seems to have inconsitency gotchas which creates hours of head scratching, just for something simple. I realise I could hard code some of this in my View Model, i.e. create my array items in the code and bind to that but I want to avoid doing that as it would mean having image paths hardcoded in code, i feel paths to images are a markup declaration.

Any help will be much appreciated.

Thanks

Paul

ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
Paulie Waulie
  • 1,690
  • 13
  • 23

1 Answers1

3

Have you used the "ditch ElementName and use Source & x:Reference" trick yet?

<Window.Resources>
    <x:Array x:Key="Items" Type="{x:Type customUITypes:ClickableImage}">
        <customUITypes:ClickableImage   x:Name="BitmapAddWorkflow"
               Command="{Binding DataContext.MyCommandOne, Source={x:Reference MainWindow}}">
            <customUITypes:ClickableImage.Bitmap>
                <BitmapImage UriSource="/Images/GalleryWorkflowAdd.png"/>
            </customUITypes:ClickableImage.Bitmap>
        </customUITypes:ClickableImage>
        <customUITypes:ClickableImage  x:Name="BitmapDeleteWorkflow"
               Command="{Binding DataContext.MyCommandTwo, Source={x:Reference MainWindow}}">
            <customUITypes:ClickableImage.Bitmap>
                <BitmapImage UriSource="/Images/GalleryWorkflowDelete.png"/>
            </customUITypes:ClickableImage.Bitmap>
        </customUITypes:ClickableImage>                                        
    </x:Array>
</Window.Resources>
<!-- ... -->
<ribbon:RibbonGallery ItemsSource="{StaticResource Items}" ...

Externalized array due to cyclical dependency (you can try to keep in place but i'm pretty sure the compiler won't like it).


Alternatively you can snatch the DataContext from a pipe object:

<Window.Resources>
    <!-- Resource declaration gives you easy access using StaticResource -->
    <FrameworkElement Name="Pipe" Visibility="Hidden"/>
</Window.Resources>
<!-- Place it somewhere in the window where it can inherit the Window's DataContext -->
<StaticResource ResourceName="Pipe"/>
<!-- ... -->
<customUITypes:ClickableImage   x:Name="BitmapAddWorkflow"
    Command="{Binding DataContext.MyCommandOne, Source={StaticResource Pipe}}">
H.B.
  • 166,899
  • 29
  • 327
  • 400
  • Works like a charm, this is why I love Stack Overflow. Many Thanks. Out of curiosity, did I sense a touch of sarcasm in the opening to your answer? I didn't mean for my question to sound conceited, I was frustrated that I couldn't figure it out, your answer in the end was quite simple but effective, I realise I have still have a lot to learn with WPF. – Paulie Waulie Nov 24 '11 at 09:48
  • Also, thanks for formatting the XAML in my question, I guess it was originally a copy paste fail :). Thanks – Paulie Waulie Nov 24 '11 at 09:49
  • @PaulieWaulie: That was not meant to be sarcastic at all, i was just recognizing the fact there are a lot of "tricks" in WPF and i doubt that anyone would know them all. Glad that worked :) – H.B. Nov 24 '11 at 09:54
  • OK, sorry, I'm a sensitive soul :p, I was just paranoid that my question was badly worded. Anyway, thanks once again for you concise and great answer :0). – Paulie Waulie Nov 24 '11 at 10:08