0
votes

I have two buttons with commands bound to them. If the user hovers over a button1 it should highlight (border color changes) textbox1 and combobox1 only when the button1 is in disabled state.

If the user hovers over a button2 it should highlight (border color changes) textbox2, textbo3 and combobox1 only when the button2 is in disabled state.

And finally unhighlight the controls on mouseleave.

Is this possible with pure XAML, because the style should be applied to other controls, not to the button itself who triggers the event and only when conditions are met? And how could this be done?

I found many examples on SO, but they do not apply to this specific case.

I started to do this programmatically:

<Button Name="btnGenerateHash"  
        IsEnabled="{Binding VM.IsGenerateButtonEnabled}"
        Command="{Binding GenerateCommand}"
        Content="{Binding VM.GenerateHashButtonLabel}" Width="160"                      
        Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Margin="10" >
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseEnter">
            <i:InvokeCommandAction Command="{Binding HighlightFieldsCommand}" CommandParameter="{Binding Source='generate,enter'}"></i:InvokeCommandAction>
        </i:EventTrigger>
        <i:EventTrigger EventName="MouseLeave">
            <i:InvokeCommandAction Command="{Binding HighlightFieldsCommand}" CommandParameter="{Binding Source='generate,leave'}"></i:InvokeCommandAction>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Button>

Modified version:

<StackPanel Orientation="Vertical">
<CheckBox 
x:Name="EnableButton1CheckBox" 
Content="Enable Button1" 
Margin="4"
/>

<Grid Margin="4">

<Button   Click="button1_Click"
Content="Button1"
x:Name="button1"
IsEnabled="{Binding IsChecked, ElementName=EnableButton1CheckBox}">

</Button>



<Border
x:Name="Button1MouseDetector"
Background="Transparent"
>
    <Border.Style>
        <Style TargetType="Border">
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Tag" Value="MouseOver" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Border.Style>
</Border>


    <!-- 
When button1 is disabled, it can't receive mouse events, so we create a 
coextensive control that's explicitly transparent. If it merely had no  
background specified, it wouldn't get mouse events either. 
-->

</Grid>


<Grid Margin="4">
<Button  
Content="Button2"
x:Name="button2"
IsEnabled="{Binding IsChecked, ElementName=EnableButton1CheckBox}">

</Button>



<Border
x:Name="Button2MouseDetector"
Background="Transparent"
>
    <Border.Style>
        <Style TargetType="Border">
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Tag" Value="MouseOver" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Border.Style>
</Border>


    <!-- 
When button1 is disabled, it can't receive mouse events, so we create a 
coextensive control that's explicitly transparent. If it merely had no  
background specified, it wouldn't get mouse events either. 
-->

</Grid>      

<TextBox  
Text="tb1"
x:Name="tb1"
Margin="4"
>
<TextBox.Style>
<Style TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
    <Style.Triggers>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition 
                Binding="{Binding Tag, ElementName=Button1MouseDetector}" 
                Value="MouseOver" 
                />
                <Condition 
                Binding="{Binding IsEnabled, ElementName=button1}" 
                Value="False" 
                />
            </MultiDataTrigger.Conditions>
            <Setter Property="BorderBrush" Value="Red" />
        </MultiDataTrigger>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition 
                Binding="{Binding Tag, ElementName=Button2MouseDetector}" 
                Value="MouseOver" 
                />
                <Condition 
                Binding="{Binding IsEnabled, ElementName=button2}" 
                Value="False" 
                />
            </MultiDataTrigger.Conditions>
            <Setter Property="BorderBrush" Value="Green" />
        </MultiDataTrigger>
    </Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</StackPanel>
1
Might give button1 a style with a trigger that sets Tag to something when mouseover, then give the other guys style multitriggers bound to button1.Tag and button1.IsEnabled. Similar deal for the others. - 15ee8f99-57ff-4f92-890c-b56153
If you could provide some code that would be great. Dont want to type that much - lokusking
@EdPlunkett, for you :-) lokusking was to quick :-). But it should only be triggered when the button is in disabled state...? - Legends
@Legends If that was for me, see edit, oops - 15ee8f99-57ff-4f92-890c-b56153
Yeah Condition Property="IsEnabled" Value="False" - 15ee8f99-57ff-4f92-890c-b56153

1 Answers

1
votes

This is partial, but illustrates how to

  1. Expose mouseover state of a possibly disabled control to XAML style triggers on other controls, and

  2. How those other XAML triggers can do stuff only when two different conditions are both true.

XAML:

<StackPanel Orientation="Vertical">
    <CheckBox 
        x:Name="EnableButton1CheckBox" 
        Content="Enable Button1" 
        Margin="4"
        />
    <Grid
        Margin="4"
        >
        <Button 
            Content="Button1"
            x:Name="button1"
            IsEnabled="{Binding IsChecked, ElementName=EnableButton1CheckBox}"
            >
        </Button>
        <!-- 
        When button1 is disabled, it can't receive mouse events, so we create a 
        coextensive control that's explicitly transparent. If it merely had no  
        background specified, it wouldn't get mouse events either. 
        -->
        <Border
            x:Name="Button1MouseDetector"
            Background="Transparent"
            >
            <Border.Style>
                <Style TargetType="Border">
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Tag" Value="MouseOver" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Border.Style>
        </Border>
    </Grid>

    <Button 
        Content="Button2"
        x:Name="button2"
        Margin="4"
        >
        <Button.Style>
            <Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
                <Style.Triggers>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition 
                                Binding="{Binding Tag, ElementName=Button1MouseDetector}" 
                                Value="MouseOver" 
                                />
                            <Condition 
                                Binding="{Binding IsEnabled, ElementName=button1}" 
                                Value="False" 
                                />
                        </MultiDataTrigger.Conditions>
                        <Setter Property="BorderBrush" Value="Red" />
                    </MultiDataTrigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>
</StackPanel>