使用ShowDialog和无边框窗口时,IsMouseOver触发器不起作用

时间:2016-08-31 20:23:33

标签: wpf triggers ismouseover

我有两个Windows申请。其中一个是MainWindow,另一个是设置。使用SettingsWindow点击设置按钮并将其ShowDialog设置为Owner时,会打开MainWindow

SettingsWindow我在窗口最底部有一个按钮,当IsMouseOverTrue红色 {蓝色为False。但是当光标在MainWindow上时它不会改变。图像在下面是清楚的。我该如何解决这个问题?

CASE:光标不在SettingsWindow中,但它保持红色,没有变化。

enter image description here

Xaml代码:

<Window x:Class="AltoSS.SettingsWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="SettingsWindow"
        Height="150"
        Width="360"
        WindowStyle="None"
        AllowsTransparency="True"
        WindowStartupLocation="CenterOwner">

  <!-- Other control codes-->
  <Button Grid.Row="2" Content="KAYDET" 
          FontSize="15"
          FontWeight="Bold"
          BorderBrush="Gray"
          BorderThickness="0,2,0,2">
    <Button.Style>
      <Style TargetType="Button">
        <Setter Property="Background" Value="Blue"/>
        <Setter Property="Template">
          <Setter.Value>
            <ControlTemplate TargetType="Button">
              <Border Background="{TemplateBinding Background}">
                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
              </Border>
              <ControlTemplate.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                  <Setter Property="Background" Value="Red"/>
                  <Setter Property="Foreground" Value="White"/>
                </Trigger>
              </ControlTemplate.Triggers>
            </ControlTemplate>
          </Setter.Value>
        </Setter>
      </Style>
    </Button.Style>
  </Button>
</Window>

3 个答案:

答案 0 :(得分:2)

好吧,经过一些研究,我找不到任何合理的理由。对我来说这似乎更像是一个错误。因此,如果有人确切知道为什么会发生这种情况,请告诉我们!

无论如何,我想出了一个解决方法。基本上,我们可以使用Show()并添加一些代码来接近模态行为 - 比如禁用父窗口,直到对话框关闭或用户选择了OK或取消为止。

示例:

SettingsWindow settingsWindow = new SettingsWindow(); 
this.IsEnabled = false; //disables the main window 
settingsWindow.Owner = this; // main window is the settings window owner 
settingsWindow.Show(); 
settingsWindow.Closed += (o, e1) => { onWindowClosed(o,e1); }; // this is the close event

订阅了settingsWindow关闭事件后,我们现在可以在settingsWindow关闭时再次启用父窗口:

private void onWindowClosed(object sender, EventArgs e)
{
    this.IsEnabled = true;
}

触发器现在可以正常工作,父窗口将被禁用,直到其子窗口关闭。

答案 1 :(得分:1)

我认为您必须手动观察鼠标位置。为此,您可以使用Peheje here发布的代码。

我用它来编写一个工作示例。在离开窗口时,Button会获得正确的样式。

using System.Runtime.InteropServices;
using Point = System.Drawing.Point;

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetCursorPos(ref Point lpPoint);

public bool IsMouseOverButton {
    get { return _isMouseOverButton; }
    set {
        if (value == _isMouseOverButton) return;
        _isMouseOverButton = value;
        OnPropertyChanged();
    }
}

public SettingsWindow()
{
    InitializeComponent();

    new Thread(() =>
    {
        while (true)
        {
            //Logic
            Point p = new Point();
            GetCursorPos(ref p);

            //Update UI
            Application.Current.Dispatcher.Invoke(() =>
            {
                double btnLeft = DlgWindow.Left;
                double btnRight = btnLeft + DlgBtn.ActualWidth;
                double btnBottom = DlgWindow.Top + DlgWindow.ActualHeight;
                double btnTop = btnBottom - DlgBtn.ActualHeight;

                IsMouseOverButton =
                    p.X >= btnLeft && p.X <= btnRight &&
                    p.Y >= btnTop && p.Y <= btnBottom;
            });

            //async wait (non blocking)
            (new ManualResetEvent(false)).WaitOne(100);
        }
    }).Start();
}

XAML

<Window x:Name="DlgWindow"
        DataContext="{Binding RelativeSource={RelativeSource Self}}" 
        AllowsTransparency="True">

  <Button x:Name="DlgBtn"
          Height="50"
          VerticalAlignment="Bottom"
          BorderBrush="Gray"
          BorderThickness="0,2,0,2"
          Content="KAYDET"
          FontSize="15"
          FontWeight="Bold">
    <Button.Style>
      <Style TargetType="Button">
        <Setter Property="Background" Value="Blue"/>
        <Setter Property="Template">
          <Setter.Value>
            <ControlTemplate TargetType="Button">
              <Border Background="{TemplateBinding Background}">
                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
              </Border>
            <ControlTemplate.Triggers>
              <DataTrigger Binding="{Binding IsMouseOverButton}" Value="True">
                <Setter Property="Background" Value="Red" />
                <Setter Property="Foreground" Value="White" />
              </DataTrigger>
            </ControlTemplate.Triggers>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
  </Button.Style>
</Button>

答案 2 :(得分:0)

这对我有用:在设置Window.Resources下定义样式资源(对于按钮) - 然后这个样式设置新模板(边框),默认背景为蓝色,IsMouseOver触发器将其更改为红色。隐式地明确引用样式(两者都适用于我)。

链接到小型测试项目:https://1drv.ms/u/s!AhlMAmchX3R6nDJ1MXS6DxlRXtnA

<Window x:Class="IsMouseOverTriggerSecondWindow.SettingsWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:IsMouseOverTriggerSecondWindow"
        mc:Ignorable="d"
        Title="SettingsWindow" Height="170" Width="330">

    <!-- my settings window button style-->
    <!-- defined as a resource in SettingsWindow.xaml, so it doesnt effect MainWindow -->
    <Window.Resources>
        <Style TargetType="Button" >
            <Setter Property="Background" Value="Blue"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border Background="{TemplateBinding Background}">
                            <ContentPresenter Content="{TemplateBinding Content}" 
                                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="Red" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>

    <Grid>
        <TextBlock Text="This is the settings window" />
        <Button Content="KAYDET" Height="30" VerticalAlignment="Bottom" Foreground="White" FontWeight="Bold" />
    </Grid>
</Window>