0

I have an ItemsControl control that displays some buttons. When I click on one of the buttons I have to show some details of the selected resource (bound to the button).

So when the button is clicked I set a property on the ViewModel called SelectedResource.

That's working fine, what I'd like to do is to highlight the button clicked.

I have a ControlTemplate for my button as follows:

<ControlTemplate x:Key="ResourceButtonTemplate" TargetType="{x:Type ButtonBase}">
    <Border Name="SelectedButtonBorder"
            CornerRadius="3">
        <Border x:Name="border" 
            BorderBrush="{TemplateBinding BorderBrush}" 
            BorderThickness="{TemplateBinding BorderThickness}" 
            CornerRadius="3"
            Background="{TemplateBinding Background}" 
            SnapsToDevicePixels="True">
            <StackPanel Orientation="Horizontal" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}">
                <Image Source="{Binding Type.Value, Converter={converter:ResourceTypeToStringConverter}}"></Image>
                <ContentPresenter x:Name="contentPresenter" 
                              ContentTemplate="{TemplateBinding ContentTemplate}" 
                              Content="{TemplateBinding Content}" 
                              ContentStringFormat="{TemplateBinding ContentStringFormat}" 
                              Focusable="False"  
                              Margin="{TemplateBinding Padding}" 
                              RecognizesAccessKey="True" 
                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
            </StackPanel>
        </Border>
    </Border>
    <ControlTemplate.Triggers>
        <DataTrigger Binding="{Binding SelectedResource}" Value="">
            <Setter TargetName="SelectedButtonBorder" Property="BorderBrush" Value="Red" />
            <Setter TargetName="SelectedButtonBorder" Property="BorderThickness" Value="2" />
        </DataTrigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

I've tried the DataTrigger, but I can't bind the value property of the datatrigger.

So, is there a way to do that using only XAML?

Edit:

I don't want to compare the SelectedResource to an empty string, I actually don't know what to compare to. I tried to compare one of the properties of the SelectedResource object to the text shown on the button.

4

3 回答 3

0

Assuming that you have correctly set the DataContext of your view to an instance of your view model, you should be able to access the SelectedResource property using a RelativeSource Binding like this:

<DataTrigger Binding="{Binding DataContext.SelectedResource, 
    RelativeSource={RelativeSource AncestorType={x:Type 
    YourViewsNamespacePrefix:YourUserControl}}}" Value="">
    <Setter TargetName="SelectedButtonBorder" Property="BorderBrush" Value="Red" />
    <Setter TargetName="SelectedButtonBorder" Property="BorderThickness" Value="2" />
</DataTrigger>

Using this Binding, the Framework will look for a parent of the Button of type YourUserControl and when it finds that, it will then look at the object set as its DataContext and then finally, look for a property named SelectedResource in that object.


UPDATE >>>

It really doesn't matter what value you use, as long as you use a value. You said when the button is clicked I set a property on the ViewModel called SelectedResource. Let's say that you store the Button.Name value in SelectedResource... then that is what you put in the DataTrigger. Of course, you'd need to create a slightly different DataTrigger for each Button:

<DataTrigger Binding="{Binding DataContext.SelectedResource, 
    RelativeSource={RelativeSource AncestorType={x:Type 
    YourViewsNamespacePrefix:YourUserControl}}}" Value="Button1">
    ...
</DataTrigger>
...
<DataTrigger Binding="{Binding DataContext.SelectedResource, 
    RelativeSource={RelativeSource AncestorType={x:Type 
    YourViewsNamespacePrefix:YourUserControl}}}" Value="Button8">
    ...
</DataTrigger>

The problem that you would then have is that you couldn't use an ItemsControl to display your Button elements.

于 2013-11-14T16:08:38.767 回答
0

Or did you try something like this:

<Button>
            <Button.Style>
                <Style TargetType="{x:Type Button}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding SelectedResource}" Value="1">
                            <Setter Property="Background"  Value="Red" />
                        </DataTrigger>
                        <DataTrigger Binding="{Binding SelectedResource}" Value="2">
                            <Setter Property="Background"  Value="White" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
于 2013-11-14T16:13:14.090 回答
0

Assuming each Button's DataContext is a given Resource, that binding in the datatrigger is failing.

I would have a bool property IsSelected in the Resource class. Then your trigger would look like this:

<DataTrigger Binding="{Binding IsSelected}" Value="True">
    <Setter TargetName="SelectedButtonBorder" Property="BorderBrush" Value="Red" />
    <Setter TargetName="SelectedButtonBorder" Property="BorderThickness" Value="2" />
</DataTrigger>

Of course, you have to handle deselection of items if only one can be selected at a time.

于 2013-11-14T16:19:26.367 回答