Я пытаюсь решить то, что кажется простой проблемой, но не могу найти простого решения. У меня есть окно в 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;
     }
  }
}

Заранее спасибо :)

1
adminSoftDK 17 Сен 2014 в 14:32
Добавьте простой стиль для всех элементов управления и примените этот стиль как при включении, так и при отключении.
 – 
Ashok Rathod
17 Сен 2014 в 14:43
Спасибо, смотрите мой комментарий ниже.
 – 
adminSoftDK
17 Сен 2014 в 16:35
Есть ли причина, по которой вы не используете ShowDialog?
 – 
Dean
17 Сен 2014 в 19:58
Да, я использую Prism, и у меня есть несколько регионов, мне нужно отключить только родителя, который открыл дочерний элемент, а не все окно позади. Другими словами, должен быть отключен только один регион. надеюсь, это имеет смысл. Диалог вообще не позволял вернуться в MainWindow.
 – 
adminSoftDK
17 Сен 2014 в 20:08
Я добавил пример проекта, который делает то, что, по моему мнению, вам нужно. Пожалуйста, смотрите сообщение ниже.
 – 
Dean
18 Сен 2014 в 00:31

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>
2
Dean 18 Сен 2014 в 17:10
Позвольте мне добавить, что вы можете изменить фон и непрозрачность элемента управления «utilityGrid» выше, чтобы показать пользователю, что что-то отключено. Возможно, оттенок или слегка приглушенный вид будут более понятны конечному пользователю.
 – 
Dean
18 Сен 2014 в 00:33
Большое спасибо за проект :). Я протестировал его, и он отлично работает, он фиксирует все события мыши, но все еще работает с клавиатурой. Таким образом, я могу перемещаться по элементам управления в MainWindow, использовать горячую клавишу Shift+c или просто использовать стрелки вверх и вниз для навигации внутри списка. Пожалуйста, посмотрите код, который я добавил в ваш файл MainWindow. Я не знал, как разместить здесь код, поэтому добавил его в ваш ответ. Любые идеи, как обойти это? С уважением
 – 
adminSoftDK
18 Сен 2014 в 12:31
1
Я получил сообщение от SO, отклоняющее ваше редактирование - я думаю, вам нужно будет опубликовать его в своем собственном сообщении. В любом случае вам придется сделать так, чтобы покрывающая сетка перехватывала все события клавиатуры. Я подожду, чтобы увидеть ваш код.
 – 
Dean
18 Сен 2014 в 15:09
Я добавил несколько строк кода в код MainWindow.xaml.cs для перехвата событий клавиатуры. Это останавливает взаимодействие с клавиатурой.
 – 
Dean
18 Сен 2014 в 17:12
Большое спасибо, это решает проблему с клавиатурой. Больше нет необходимости публиковать код, я хотел опубликовать, потому что это дополнение делает свою работу :)
 – 
adminSoftDK
18 Сен 2014 в 17:50

Ваше требование нет тривиально и потребует от вас усилий для его достижения. Значения по умолчанию ControlTemplate для каждого элемента управления указывают, что они должны иметь особый вид, когда они отключены. Чтобы удалить это, вам необходимо предоставить новые ControlTemplate для все элементы управления, которые вам нужны.

Вы можете сделать это, начав с значений по умолчанию ControlTemplate для каждого элемента управления и удалив соответствующий код, который обрабатывает свойство IsEnabled или элемент Disabled VisualState. Вы можете найти большинство стандартных ControlTemplate для каждого элемента управления в Стили и шаблоны элементов управления в MSDN.

Например, это происходит из значения по умолчанию 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, его внешний вид не изменился.

0
Sheridan 17 Сен 2014 в 15:04
Спасибо, я пробовал что-то очень похожее, однако будут случаи, когда мне нужно, чтобы элементы управления были в отключенном состоянии. Что мне нужно, так это заставить элемент управления выглядеть включенным, но на самом деле он неактивен, например, пользователь не может нажать кнопку, не может ввести текст в текстовое поле и т. д.
 – 
adminSoftDK
17 Сен 2014 в 16:34
Я знаю, чего вы хотите, потому что прочитал ваш вопрос. Я сказал вам, как делать то, что вы хотите, поэтому я не очень понимаю ваш комментарий.
 – 
Sheridan
17 Сен 2014 в 16:49
Я не вижу, чтобы изменение стиля помогало, потому что, когда я открываю «дочернее» окно поверх «родительского» окна, мне нужно сделать элементы управления, которые находятся в «родительском» окне, неактивными, поэтому кнопка все еще выглядит кликабельной, но не является текстовое поле по-прежнему выглядит так, как будто оно может принимать ввод, но не может. Затем мне понадобится возможность отключить элемент управления в моем «дочернем» окне и, следовательно, сделать его фактически отключенным. Надеюсь, это поможет.
 – 
adminSoftDK
17 Сен 2014 в 17:47
Разве я только что не сказал тебе, что знаю, чего ты хочешь? Я хочу, чтобы окно сзади было отключено... поэтому установите для IsEnabled значение false. Я также хочу, чтобы его внешний вид не менялся... поэтому определите некоторые Style, которые НЕ меняют внешний вид отключенных элементов управления. Я пытаюсь решить то, что выглядит как простая проблема... это на самом деле простая проблема.
 – 
Sheridan
17 Сен 2014 в 17:51
@ Дин, я предполагаю, что вы задаете вопрос автору, а не мне, а также что вы имели в виду ShowDialog, а не ShowModal. Это хороший момент, но, пожалуйста, прокомментируйте вопрос, чтобы поговорить с автором вопроса... комментирование ответов обычно предназначено для авторов ответов.
 – 
Sheridan
17 Сен 2014 в 19:36