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

时间:2013-12-19 19:00:04

标签: wpf xaml mvvm

这很难解释,但请耐心等待。

我正在使用MVVM模式在WPF中创建应用程序。我是新手,这就是我问这个问题的原因。

我在窗口中将应用程序设置为3页或视图。其中一个是静态的,总是在那里,另外两个是几个小的设置页面,使用zindex在顶部的顶部打开。此时打开这些页面的菜单使用带有togglebuttons的列表框作为其模板(已选中状态绑定到列表框),以便您可以单击打开菜单,然后再次单击该按钮将其关闭。

在一个理想的世界中,我喜欢它,以便如果菜单页失去焦点(听一下静态视图?),设置视图也会关闭。此外,我想知道是否有人有一个更简单的解决方案,菜单以类似的方式工作,因为目前这是一个非常混乱的解决方案。以下是一些代码示例:

    <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}"/>

我正在使用此 blog post 中的概念来管理我的视图和视图模型,但是我更改了菜单的显示方式,因此我可以删除对更改页面命令的需要/ ICommand的。

TL; DR:我正在寻找建议和批评,以改善我目前创建菜单栏的方式。

2 个答案:

答案 0 :(得分:0)

如果你真的想做MVVM风格,当它失去焦点时关闭View,我会创建一个附加属性。

    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();
                };
        }
    }

在您的视图中,您可以附加在丢失焦点时要关闭的任何ViewModel,例如你的SettingsView获得了LostFocus,它将关闭该视图。在这里,我在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}"/>

答案 1 :(得分:0)

您可以在按钮上附加ContextMenu,单击按钮时会打开该按钮。这样,关闭时不关注的行为完全是自动的。

然后您可以重新设置菜单以查找您想要的内容。