Bind adorner property to viewmodel property

2019-08-03 17:10发布

问题:

I need to display (or not) an adorner depending on a viewmodel's property.

My view is like this :

<ItemsControl x:Name="Items">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Canvas.Left" Value="{Binding Path=X}" />
            <Setter Property="Canvas.Top" Value="{Binding Path=Y}" />
            <Setter Property="Width" Value="{Binding Path=Width}" />
            <Setter Property="Height" Value="{Binding Path=Height}" />
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <AdornerDecorator>
                <Border x:Name="DraggableBorder" Background="{Binding Path=BackgroundColor}">
                    <!-- contents -->

                    <i:Interaction.Behaviors>
                        <behaviors:DragOnCanvasBehavior DraggableItem="{Binding}">
                            <behaviors:DragOnCanvasBehavior.MouseOverAdornerTemplate>
                                <DataTemplate>
                                    <Border DataContext="DraggableBorder"
                                        BorderBrush="#B0000000"
                                        Width="{Binding Path=Width}"
                                        Height="{Binding Path=Height}" />
                                </DataTemplate>
                            </behaviors:DragOnCanvasBehavior.MouseOverAdornerTemplate>
                            <behaviors:DragOnCanvasBehavior.SelectedAdornerTemplate>
                                <DataTemplate>
                                    <Border DataContext="DraggableBorder"
                                        BorderBrush="#FF34619E"
                                        Width="{Binding Path=Width}"
                                        Height="{Binding Path=Height}"
                                        Visibility="{Binding Path=Selected,
                                            ElementName=DraggableBorder,
                                            Converter={StaticResource BooleanToVisibilityConverter}}" />
                                </DataTemplate>
                            </behaviors:DragOnCanvasBehavior.SelectedAdornerTemplate>
                        </behaviors:DragOnCanvasBehavior>
                    </i:Interaction.Behaviors>
                </Border>
            </AdornerDecorator>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

And the behavior attaches the mouse events to the proper methods, and displays/hides the mouse over adorner.

The mouse over/out events and adorners are working fine, but the selection adorners cause me a bit of trouble. Because only one item should be selected, I want to rely on the Selected property of the viewmodel. I assumed what is in the sample above would work (I tried a few versions), but alas, it is not to be.

How should I write my Visibility property ?

Full code available here : https://github.com/cosmo0/DragSnap/tree/adorners

回答1:

The Visibility binding binds with a property 'Selected' of DraggableBorder, which does not exist.

Furthermore, the border has a DataContext="DraggableBorder" which in this case, is a simple string.

So, use the following properties on your border:

    <Border DataContext="{Binding DataContext, ElementName=DraggableBorder}" Visibility="{Binding Selected, Converter=...}"/>