Закрытие всплывающего окна, когда его родитель свернут - PullRequest
0 голосов
/ 28 октября 2010

Я уже давно борюсь с этим и, похоже, не могу найти правильного решения.Это сценарий урезанный.Представьте, что у вас есть следующий XAML:

<Grid x:Name="LayoutRoot" Background="White">
    <Grid x:Name="Host" Width="200" Height="200">
        <Popup IsOpen="True">
            <Button Content="Some Button" Click="Button_Click" />
        </Popup>
    </Grid>
</Grid>

В обработчике событий Button_Click все, что я делаю, это сворачиваю сетку с именем Host .

private void Button_Click(object sender, RoutedEventArgs e)
{
    this.Host.Visibility = System.Windows.Visibility.Collapsed;
}

Чего я ожидал, так это того, что всплывающее окно закроется, поэтому сокрыт кнопку.Я понимаю, что всплывающие окна не находятся в том же VisualTree, и я понимаю, почему это может работать не так, как я ожидаю, но должен быть какой-то механизм, чтобы это происходило автоматически.Единственный обходной путь, который мне приходит в голову, - это LayoutUpdated, чтобы пройти вверх по визуальному дереву и спросить каждого родителя Button, если он видим, и если я встретил свернутого родителя -> закройте Popup.Однако представьте, что хит производительности имеет ОГРОМНОЕ визуальное дерево.Безумно обходить визуальное дерево на каждом проходе макета.Я открыт для любых предложений.

РЕДАКТИРОВАТЬ: Кажется, я не объяснил полностью мой сценарий.Дело в том, чтобы свернуть всплывающее окно, если ЛЮБОЙ его родителя свернут (а не только непосредственный).В WPF есть полезное свойство под названием IsVisible , которое отличается от Visibility.Например, Visibility все еще может быть Visible , но IsVisible будет false в этом сценарии.

С наилучшими пожеланиями, K

Ответы [ 2 ]

0 голосов
/ 28 октября 2010

Я думаю, что вы нашли ошибку или, по крайней мере, "странность" во всплывающем элементе управления - проверьте это:

Сначала я думал просто привязать видимость всплывающего окна к хосту.Это ДОЛЖНО работать.

    <Grid x:Name="LayoutRoot" Background="White">
    <Grid x:Name="Host" Width="200" Height="200" Background="Aqua">
        <Popup IsOpen="True" Visibility="{Binding ElementName=Host, Path=Visibility}" Height="100" Width="100">
            <Button Content="Some Button" Click="Button_Click"/>
        </Popup>
    </Grid>
</Grid>

Но это не работает.Сетка "Host" исчезает, но я все еще вижу кнопку.Это смутило меня, поэтому я запустил Silverlight Spy и проверил это - настройка видимости всплывающего окна НЕ скрывает кнопку!

См. Демонстрационное видео

В любом случае, чтобы сделать это, вам просто нужно немного помассировать вещи, чтобы связать видимость хоста со свойством IsOpen.Я использовал конвертер здесь:

<UserControl.Resources>
    <Junk:VisibilityToBoolConverter x:Key="VisibilityToBoolConverter"/>
</UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White">
    <Grid x:Name="Host" Width="200" Height="200" Background="Aqua">
        <Popup IsOpen="{Binding ElementName=Host, Path=Visibility, Converter={StaticResource VisibilityToBoolConverter}}" Height="100" Width="100">
            <Button Content="Some Button" Click="Button_Click"/>
        </Popup>
    </Grid>
</Grid>

private void Button_Click(object sender, RoutedEventArgs e)
{
    this.Host.Visibility = System.Windows.Visibility.Collapsed;

}


public class VisibilityToBoolConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return ((Visibility) value) == Visibility.Visible;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Это работает для меня.

0 голосов
/ 28 октября 2010

Если вы просто хотите закрыть всплывающее окно, почему бы не установить IsOpen в всплывающем окне на false.

<Grid x:Name="LayoutRoot" Background="White">
    <Grid x:Name="Host" Width="200" Height="200">
        <Popup x:Name="HostPopup" IsOpen="True">
            <Button Content="Some Button" Click="Button_Click" />
        </Popup>
    </Grid>
</Grid>

private void Button_Click(object sender, RoutedEventArgs e)
{
   this.HostPopup.IsOpen = false;
}

Это закрывает всплывающее окно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...