9

我有一个带有文本框的数据模板和一个带有一些样式的按钮。当焦点位于旁边的文本框上时,我想让按钮显示鼠标悬停状态。这可能吗?

我想它会涉及到这样的事情。我可以通过使用 FindVisualChild 和 FindName 来获取文本框。然后我可以在文本框上设置 GotFocus 事件来做一些事情。

_myTextBox.GotFocus += new RoutedEventHandler(TB_GotFocus);

在 TB_GotFocus 中我被卡住了。我可以获得想要显示鼠标悬停状态的按钮,但我不知道要发送什么事件给它。不允许 MouseEnterEvent。

void TB_GotFocus(object sender, RoutedEventArgs e)
  {
     ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(this.DataTemplateInstance);
     DataTemplate template = myContentPresenter.ContentTemplate;

     Button _button= template.FindName("TemplateButton", myContentPresenter) as Button;
     _button.RaiseEvent(new RoutedEventArgs(Button.MouseEnterEvent));

  } 
4

2 回答 2

2

我认为不可能伪造事件,但您可以强制按钮呈现自身,就好像它有 MouseOver。

private void tb_GotFocus(object sender, RoutedEventArgs e)
{
    // ButtonChrome is the first child of button
    DependencyObject chrome = VisualTreeHelper.GetChild(button, 0);
    chrome.SetValue(Microsoft.Windows.Themes.ButtonChrome.RenderMouseOverProperty, true);
}

private void tb_LostFocus(object sender, RoutedEventArgs e)
{
    // ButtonChrome is the first child of button
    DependencyObject chrome = VisualTreeHelper.GetChild(button, 0);
    chrome.ClearValue(Microsoft.Windows.Themes.ButtonChrome.RenderMouseOverProperty);
}

您需要参考 PresentationFramework.Aero.dlll 才能使其正常工作,然后它将仅适用于 Aero 主题的 Vista。

如果您希望它适用于其他主题,您应该为您想要支持的每个主题制作自定义控件模板。

有关提示,请参阅http://blogs.msdn.com/llobo/archive/2006/07/12/663653.aspx

于 2009-01-21T09:33:16.903 回答
0

作为对 jesperll 评论的跟进,我认为您可以通过将样式动态设置为您想要的样式/为空来为每个主题制作自定义模板。

这是我的窗口,定义了样式(但未设置任何内容)。

<Window x:Class="WpfApplication.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication"
Title="Window1" Height="300" Width="300">

<Window.Resources>
    <Style TargetType="{x:Type Button}" x:Key="MouseOverStyle">
        <Setter Property="Background">
            <Setter.Value>Green</Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<Grid Height="30">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="3*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <TextBox x:Name="MyTextBox" Grid.Column="0" Text="Some Text" Margin="2" GotFocus="TextBox_GotFocus" LostFocus="MyTextBox_LostFocus"/>
    <Button x:Name="MyButton" Grid.Column="1" Content="Button" Margin="2" MouseEnter="Button_MouseEnter" MouseLeave="Button_MouseLeave" />
</Grid>

您可以在 .cs 文件中使用事件,而不是通过模板中的触发器设置样式,如下所示:

...

    public partial class Window1 : Window
{
    Style mouseOverStyle;
    public Window1()
    {
        InitializeComponent();
        mouseOverStyle = (Style)FindResource("MouseOverStyle");
    }
    private void TextBox_GotFocus(object sender, RoutedEventArgs e) { MyButton.Style = mouseOverStyle; }
    private void MyTextBox_LostFocus(object sender, RoutedEventArgs e) { MyButton.Style = null; }
    private void Button_MouseEnter(object sender, MouseEventArgs e) { ((Button)sender).Style = mouseOverStyle; }
    private void Button_MouseLeave(object sender, MouseEventArgs e) { ((Button)sender).Style = null; }
}

您在构造函数中获得对样式的引用,然后动态设置/取消设置它。这样,您可以定义您希望您的样式在 Xaml 中的样子,并且您不必依赖任何新的依赖项。

于 2009-01-26T15:21:15.003 回答