Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

wpf - Bind to DataContext Property inside inline Array Declaration

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...