WPF - IsMouseOver binding to visibility

I have a window that overrides RadioButton ControlTemplateto show a user control inside it. Inside a user control, I have an attached button visibility IsMouseOverthat works correctly when the button is shown only when the mouse is overhanging the control. However, when I click on RadioButton, it Buttondisappears. After some debugging and reading, it seems to RadioButtonfix a mouse click, and this makes IsMouseOverfor UserControlfalse.

I tried to attach visibility Buttonto FindAncestor {x:Type RadioButton}, and it works, but it seems a little fragile to me, UserControldepending on who contains it. The code for the window and the user control are shown below. Any suggestions?

<Window x:Name="window" x:Class="WPFTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:WPFTest="clr-namespace:WPFTest"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <Style TargetType="{x:Type RadioButton}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type RadioButton}">
                        <WPFTest:TestUC />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Border BorderBrush="Black" BorderThickness="2">
        <StackPanel>
            <RadioButton x:Name="OptionButton" Height="100" />
            <TextBlock Text="{Binding ElementName=OptionButton, Path=IsMouseOver}" />
        </StackPanel>
    </Border>
</Window>

<UserControl x:Name="_this" x:Class="WPFTest.TestUC"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300">
    <UserControl.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
    </UserControl.Resources>
    <StackPanel>
        <TextBlock Text="SomeText" />
        <TextBlock Text="{Binding ElementName=_this, Path=IsMouseOver}" />
        <Button x:Name="_cancelTextBlock" Content="Cancel" Visibility="{Binding ElementName=_this, Path=IsMouseOver, Converter={StaticResource BooleanToVisibilityConverter}}" />
    </StackPanel>
</UserControl>
+3
source share
3 answers

I seem to have fixed the problem by setting a trigger in a control template that binds to RadioButton IsMouseOver and sets a custom DependencyProperty in UserControl.

Sort of:

<ControlTemplate TargetType="{x:Type RadioButton}">
    <WPFTest:TestUC x:Name="UC" />
    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="ShowCancel" Value="True" TargetName="UC"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

I am still confused why Mouse Capture fakes IsMouseOver in a UserControl child of RadioButton. Can someone shed some light on this?

+1
source

, RadioButton, , . , .

handledEventsToo.

, , xaml. .

+1

. , UserControl IsMouseOver false, TextBlock (s) .

, ... , .

RadioButton ( ), Control? ( , IsMouseOver false - , Button.)

xaml ...

<Window
    x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="Window1"
    Width="300"
    Height="300"
>
    <Window.Resources>
        <Style TargetType="{x:Type Control}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Control}">
                        <local:UserControl1/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

    <Border BorderBrush="Black" BorderThickness="2">
        <StackPanel>
            <Control x:Name="OptionButton" Height="100"/>
            <TextBlock Text="{Binding ElementName=OptionButton, Path=IsMouseOver}"/>
        </StackPanel>
    </Border>
</Window>

EDIT:

I just wanted to add ... that if you agree with the above approach ... then the right thing probably is to just use UserControl in the visual tree of Window and reinstall Control. So ... like this:

<Window
    x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    Title="Window1"
    Width="300"
    Height="300"
>
    <Border BorderBrush="Black" BorderThickness="2">
        <StackPanel>
            <local:UserControl1 x:Name="OptionButton" Height="100"/>
            <TextBlock Text="{Binding ElementName=OptionButton, Path=IsMouseOver}"/>
        </StackPanel>
    </Border>
</Window>
0
source

Source: https://habr.com/ru/post/1699055/


All Articles