2009-01-21 103 views
8

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

我想它会涉及到这样的事情。我可以通过使用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)); 

    } 
+0

你可以发布你的控制模板给我们看吗? – 2009-01-23 19:02:56

回答

2

我不认为这是可能的假事件,但你可以强制按钮来表现自己仿佛它有鼠标悬停。

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这个工作,然后它会在Vista的Aero主题才起作用。

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

小费

http://blogs.msdn.com/llobo/archive/2006/07/12/663653.aspx
+0

这对大多数我怀疑的人都有效,但我使用的是自定义按钮模板,所以默认的Windows主题不适用于我。 – Jippers 2009-01-21 19:18:04

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中看起来像什么,而且你不必依赖任何新的依赖关系。