禁用父窗口,而不更改任何控件的可视外观

时间:2014-09-17 10:32:01

标签: wpf styles childwindow

我试图解决看起来像一个简单的问题,但我找不到一个简单的解决方案。 我在wpf中有一个窗口,该窗口只包含一个列表框,其中包含少量名称和一个按钮,该按钮不执行任何操作。当您单击列表框中的某个项目时,它会创建并显示一个新窗口(子窗口)。此时我希望后面的窗口被禁用,但我也希望它的外观不会改变。然而,列表框和按钮(或我放在该窗口上的任何其他控件)会改变它们的颜色。 我如何以最简单的方式实现上述目标?

以下是代码:

<Window x:Class="MainWindowStyleAndBehaviour.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" WindowState="Maximized" Name="myWindow">
<Grid Background="Green">
    <ListBox Name="myListbox" HorizontalAlignment="Left" VerticalAlignment="Top" Height="200"     Width="300" Background="Red" FontSize="30" SelectionChanged="myListbox_SelectionChanged" Margin="10"/>
    <Button Content="Don't click me" Width="300" Height="60" HorizontalAlignment="Right" VerticalAlignment="Top" FontSize="30" Margin="10"/>
</Grid>
</Window>

 namespace MainWindowStyleAndBehaviour
 {
   public partial class MainWindow : Window
   {
     public MainWindow()
     {
        InitializeComponent();
        Names = new List<string>() { "Sonia", "Bruno", "Cezar" };
        myListbox.ItemsSource = Names;
     }

     public List<string> Names { get; set; }

     private void myListbox_SelectionChanged(object sender, SelectionChangedEventArgs e)
     {
        Window w = new Window();
        myWindow.IsEnabled = false;
        w.Show();
        w.Closed += (s, ea) => myWindow.IsEnabled = true;
     }
  }
}

提前谢谢你:)

2 个答案:

答案 0 :(得分:2)

您可以在主窗口上叠加网格控件,并将其折叠为开头。当您打开弹出窗口(下面称为OtherWindow)时,使此网格可见。因为它位于所有其他控件之上,所以它将捕获所有鼠标事件,有效地禁用整个窗口而不改变其外观。

MainWindow.xaml.cs

using System.Windows;
using System.Windows.Input;

namespace Test
{
  public partial class MainWindow : Window
  {
    public MainWindow()
    {
      InitializeComponent();
    }

    private void listbox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
      utilityGrid.Visibility = System.Windows.Visibility.Visible;    // <- Crux
      OtherWindow otherWindow = new OtherWindow(ReturnToEnabled);
      PreviewKeyDown += MainWindow_PreviewKeyDown;
      otherWindow.Show();
    }

    private void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e)
    {
      e.Handled = true;
    }

    private void ReturnToEnabled()
    {
      utilityGrid.Visibility = System.Windows.Visibility.Collapsed;
      PreviewKeyDown -= MainWindow_PreviewKeyDown;
    }
  }
}

MainWindow.xaml

<Window x:Class="Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="200" Width="300" WindowStartupLocation="CenterScreen">
    <Grid  >
      <Grid x:Name="PutYourStuffInHere">
      <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
      </Grid.RowDefinitions>
      <ListBox Grid.Row="0" MouseDoubleClick="listbox_MouseDoubleClick" >
        <ListBoxItem>Double-Click</ListBoxItem>
        <ListBoxItem>Sample</ListBoxItem>
        <ListBoxItem>Text</ListBoxItem>
      </ListBox>
    </Grid>
    <Grid x:Name="utilityGrid" Background="White" Opacity="0.0" Visibility="Collapsed"></Grid>
  </Grid>
</Window>

OtherWindow.xaml.cs

using System;
using System.Windows;

namespace Test
{
  public partial class OtherWindow : Window
  {
    Action _returnToEnabled;
    public OtherWindow(Action ReturnToEnabled)
    {
      InitializeComponent();
      _returnToEnabled = ReturnToEnabled;
    }

    private void buttonClose_Click(object sender, RoutedEventArgs e)
    {
      Close();
    }

    private void OtherWindow_Closed(object sender, EventArgs e)
    {
      if (_returnToEnabled != null)
        _returnToEnabled();
    }
  }
}

OtherWindow.xaml

<Window x:Class="Test.OtherWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="OtherWindow" Height="300" Width="300" WindowStyle="ToolWindow"
        Closed="OtherWindow_Closed">
    <Grid>
    <Button Width="100" Height="25" x:Name="buttonClose" Click="buttonClose_Click">Close</Button>
    </Grid>
</Window>

答案 1 :(得分:0)

您的要求是微不足道的,需要您努力实现它。每个控件的默认ControlTemplate指定它们在禁用时应具有不同的外观。要删除它,您必须provide new ControlTemplates 所有与您相关的控件。

您可以通过从每个控件的默认ControlTemplate开始并删除处理IsEnabled属性或Disabled VisualState元素的相关代码来执行此操作。您可以在MSDN上的Control Styles and Templates页面中找到每个控件的大多数默认ControlTemplate

例如,这来自链接页面中ControlTemplate的默认Button

<VisualState x:Name="Disabled">
    <Storyboard>
      <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).
          (GradientBrush.GradientStops)[1].(GradientStop.Color)"
                                    Storyboard.TargetName="Border">
        <EasingColorKeyFrame KeyTime="0"
                             Value="{StaticResource DisabledControlDarkColor}" />
      </ColorAnimationUsingKeyFrames>
      <ColorAnimationUsingKeyFrames
          Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
                                    Storyboard.TargetName="Border">
        <EasingColorKeyFrame KeyTime="0"
                             Value="{StaticResource DisabledForegroundColor}" />
      </ColorAnimationUsingKeyFrames>
      <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).
          (GradientBrush.GradientStops)[1].(GradientStop.Color)"
                                    Storyboard.TargetName="Border">
        <EasingColorKeyFrame KeyTime="0"
                             Value="{StaticResource DisabledBorderDarkColor}" />
      </ColorAnimationUsingKeyFrames>
    </Storyboard>
</VisualState>

您可以使用自己的颜色替换它,或者只是删除它,这样当控件的IsEnabled属性为true时,其外观就不会发生变化。< / p>