2016-08-31 8 views
8

私は2つのアプリケーションにWindowsを持っています。そのうちの1つはMainWindowで、もう1つは設定用です。 ShowDialogを使用し、OwnerMainWindowに設定すると、設定ボタンをクリックするとSettingsWindowが開きます。 SettingsWindowShowDialogとフチ無しのウィンドウを使用しているときにIsMouseOverトリガが機能しない

Iは、ウィンドウの最下部にあるボタンを有し、IsMouseOverFalseためTrue青色である場合には、赤色に色を変化させます。しかし、カーソルがMainWindow上にあるときは変更されません。画像は以下の通りです。この問題を解決するにはどうすればよいですか?

ケース:カーソルは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> 
+0

どのようにトリガーされますか?あなたのxamlを共有してください – Forlani

+0

ああ、申し訳ありません。私はそれを追加することを忘れました。 Q: –

+0

@jstreetを更新する予定です。境界線のないウィンドウを作成したいと思います。問題がAllowTransparencyである場合、どうすれば解決できますか? –

答えて

2

さてさて、いくつかの研究を行った後、私はこれが発生するために何らかの論理的な理由を見つけることができませんでした。それは私のバグのように思えます。だから誰もがなぜこれが起こるのか正確に知っていれば、私たちに知らせてください!

とにかく、私は回避策を考え出しました。基本的には、Show()を使用して、モーダルの動作に近づくためのコードを追加することができます。例えば、ダイアログが閉じられるか、ユーザーがOKまたはCancelを選択するまで親ウィンドウを無効にするなどです。

例:

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

トリガーは正しく動作しますし、親ウィンドウが取得されます。settingsWindowが閉じますとき

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クローズイベントにサブスクライブした後、私たちは今、再び親ウィンドウを有効にすることができますその子供が閉じられるまで無効にされます。

+1

問題は、ダイアログウィンドウがメインウィンドウからのビジュアルツリーの一部ではないということです。カーソルが移動してウィンドウを離れると、マウスがウィンドウスコープにないため、プロパティIsMouseOverおよびRouteEvents(MouseLeave)は実行されません。 bahaviourを取得するには、ダイアログをMainWindowに統合し(workaraoundとして)、Visibiltyを切り替えてダイアログを表示/非表示にする必要があります。マウスがボタンの境界を離れると、IsMouseOverプロパティが実行されます。 – WPFGermany

+0

私はあなたが正しいと思う@Fabian、これが発生する理由です。しかし、それは奇妙な行動だ – Forlani

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

助けてくれてありがとう。しかし、あなたのプロジェクトでは、両方のWindowsがボーダレスでなければなりません。したがって、AllowsTransparency = "True" WindowStyle = "None" 'を設定する必要があります。私はそれが境界のあるウィンドウで動作していることを知っています。フチ無しの窓で作業する必要があります。 –

+0

あなたは正しいです。違いがあります。境界線を取り除く必要がある場合は、AllowsTransparency = "True"を削除すると問題が解決されますが、これを試したことがあります。 – Fredrik

+0

WindowStyle = "None"のみを設定すると、境界線のサイズが変更されたままになります。 'AllowsTransparency =" True "WindowStyle =" None "'または 'ResizeMode =" NoResize "WindowStyle =" None "'を使用する必要があります –

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> 
関連する問題