代码之家  ›  专栏  ›  技术社区  ›  DavidN

wpf-将ismouseover绑定到可见性

  •  3
  • DavidN  · 技术社区  · 16 年前

    我有一个窗口可以覆盖 RadioButton ControlTemplate 显示其中的自定义控件。在自定义控件中,我有一个按钮的可见性 IsMouseOver ,仅当鼠标悬停在控件上时才正确显示按钮。但是,当我单击 单选按钮 , the Button 消失。经过一些调试和阅读,似乎 单选按钮 在单击时捕获鼠标,这使得 伊斯莫赛弗 对于 UserControl 错误的。

    我试着把 纽扣 的可见性 FindAncestor {x:Type RadioButton} 它是有效的,但对我来说,它似乎有点脆弱 用户控制 取决于谁在控制它。窗口和用户控件的代码如下。有什么建议吗?

    <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 回复  |  直到 13 年前
        1
  •  1
  •   sirrocco    16 年前

    事件由RadioButton处理后,仅 设置 但事实上,它仍然在冒泡。所以您只需要指定您也要处理处理的事件。

    你需要看的是 handledEventsToo .

    不幸的是,我认为它不能在XAML中设置。只有代码。

        2
  •  1
  •   Arseni Mourzenko    13 年前

    我似乎通过在控件模板中设置一个触发器来解决这个问题,该模板绑定到RadioButton的IsMouseOver,并在用户控件上设置一个自定义的DependencyProperty。

    类似:

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

    但是,我仍然不明白为什么鼠标捕获会在RadioButton的UserControl子级上伪造Ismouseover。有人能解释一下吗?

        3
  •  0
  •   cplotts    16 年前

    很有趣的问题。我自己想知道,当用户控件中的文本块被鼠标按下时,为什么用户控件IsMouseOver更改为false。

    然而,这里有另一种解决方法…也许你会更喜欢这种方法。

    为什么不使用控制按钮而不使用单选按钮(因为您正在重新测试它)? (我认为IsMouseOver正变为false,因为它是一个按钮派生的控件。)

    下面是窗口的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>
    

    编辑:

    我只是想补充一下…如果你同意上述方法…然后,正确的做法可能只是使用窗口的可视化树中的用户控件,而不是重新执行控件。所以…这样地:

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