Wpf 需要在失去焦点时关闭的切换菜单

Wpf 需要在失去焦点时关闭的切换菜单,wpf,xaml,mvvm,Wpf,Xaml,Mvvm,这将很难解释,但请容忍我 我正在使用MVVM模式在WPF中创建一个应用程序。我是新手,这就是为什么我要问这个问题 我将应用程序设置为一个窗口内的3个页面或视图。其中一个是静态的,并且总是在那里,另外两个是一些小的设置页面,使用zindex在所有内容的顶部的上角打开。目前,打开这些页面的菜单使用带有切换按钮的列表框作为模板(选中状态绑定到列表框),这样您可以单击打开菜单,然后再次单击按钮关闭它 在一个理想的世界里,我希望这样,如果菜单页面失去焦点(听静态视图上的点击?),设置视图也会关闭。我还想知

这将很难解释,但请容忍我

我正在使用MVVM模式在WPF中创建一个应用程序。我是新手,这就是为什么我要问这个问题

我将应用程序设置为一个窗口内的3个页面或视图。其中一个是静态的,并且总是在那里,另外两个是一些小的设置页面,使用zindex在所有内容的顶部的上角打开。目前,打开这些页面的菜单使用带有切换按钮的列表框作为模板(选中状态绑定到列表框),这样您可以单击打开菜单,然后再次单击按钮关闭它

在一个理想的世界里,我希望这样,如果菜单页面失去焦点(听静态视图上的点击?),设置视图也会关闭。我还想知道是否有人有一个更简单的菜单解决方案,以类似的方式工作,因为目前它是一个相当混乱的解决方案。以下是一些代码示例:

    <ListBox Grid.Row="0" Grid.Column="0" ItemsSource="{Binding PageViewModels}" SelectedItem="{Binding CurrentPageViewModel}">

        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <TextBlock Margin="10,0" Text="{Binding Name}" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="#FCCC"/>
                    <ToggleButton
                            VerticalAlignment="Stretch"
                            Content=""
                            IsChecked="{Binding IsSelected, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"
                            />
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

    <!-- Settings views -->
    <ContentControl Panel.ZIndex="2" Grid.Row="1" Grid.Column="0" Content="{Binding CurrentPageViewModel}"/>

    <!-- Main page view -->
    <ContentControl Grid.Row="1" Grid.RowSpan="2" Grid.ColumnSpan="2" Width="1000" Height="700" Content="{Binding StaticPageViewModel}"/>

我正在使用此中的概念来管理我的视图和视图模型,但是我更改了菜单的显示方式,这样就不需要更改页面命令/ICommand


TL;DR:我正在寻找一些建议和批评,我可以做些什么来改进我目前创建菜单栏的方式。

如果你真的想使用MVVM样式在视图失去焦点时关闭视图,我会创建一个附加属性

    public static readonly DependencyProperty CloseViewOnLostFocusProperty =
        DependencyProperty.RegisterAttached("CloseViewOnLostFocus", typeof (object), typeof (MainWindow), new FrameworkPropertyMetadata(default(object), RegisterLostFocus));

    private static void RegisterLostFocus(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        //This is the control that is attached to it e.g. ContentControl
        var sender = dependencyObject as FrameworkElement;

        //Your ViewModel
        var viewModel = dependencyPropertyChangedEventArgs.NewValue as ViewModel;
        if (sender != null)
        {
            sender.LostFocus += (o, args) =>
                {
                    //Close whatever you are doing right now to close the View.
                    viewModel.Close();
                };
        }
    }
在你的视图上,你可以附加任何你想在失去焦点时关闭的视图模型,例如,你的设置视图失去焦点,它将关闭该视图。在这里,我在MainWindow类上创建了一个附加属性

    <!-- Settings views -->
    <ContentControl
MainWindow.CloseViewOnLostFocus="{Binding RelativeSource={RelativeSource Self},Path=Content}"
x:Name="SettingsView" Panel.ZIndex="2" Grid.Row="1" Grid.Column="0" Content="{Binding CurrentPageViewModel}"/>

    <!-- Main page view -->
    <ContentControl x:Name="MainPageView" Grid.Row="1" Grid.RowSpan="2" Grid.ColumnSpan="2" Width="1000" Height="700" Content="{Binding StaticPageViewModel}"/>

您可以在按钮上附加一个
上下文菜单
,该菜单在单击按钮时打开。通过这种方式,非聚焦行为时的关闭是完全自动的


然后,您可以重新设置菜单的样式,使其外观符合您的要求。

定义关闭,您的意思是在失去焦点时隐藏切换菜单?不,我的意思是关闭它们所代表的视图,抱歉,我没有说清楚。基本上目前双向绑定使
CurrentPageViewModel
属性为空,因此视图被关闭。因此您需要一个关闭“视图”的切换按钮吗?它已经关闭了,但我想看看是否可以使视图失去焦点(即单击主视图),然后关闭。