C# 带MVVM的地铁立交桥

C# 带MVVM的地铁立交桥,c#,wpf,xaml,mvvm,mahapps.metro,C#,Wpf,Xaml,Mvvm,Mahapps.metro,我正在尝试在我的应用程序中使用MahApps.Metro的弹出按钮。因此,我将此部分添加到MainWindow.xaml中: <controls:MetroWindow.Flyouts> <controls:FlyoutsControl ItemsSource="{Binding Flyouts}"> <controls:FlyoutsControl.ItemTemplate> <DataTemplate

我正在尝试在我的应用程序中使用MahApps.Metro的弹出按钮。因此,我将此部分添加到MainWindow.xaml中:

<controls:MetroWindow.Flyouts>
    <controls:FlyoutsControl ItemsSource="{Binding Flyouts}">
        <controls:FlyoutsControl.ItemTemplate>
            <DataTemplate DataType="{x:Type viewModel:SettingsViewModel}">
                <view:SettingsFlyout/>
            </DataTemplate>
        </controls:FlyoutsControl.ItemTemplate>
    </controls:FlyoutsControl>
</controls:MetroWindow.Flyouts>
以及如何使用
Visible
-属性:

<controls:Flyout x:Class="MyApplication.View.SettingsFlyout"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
                 Header="Settings"
                 Position="Right"
                 IsOpen="{Binding Visible}"
                 Width="300">
    ...
</controls:Flyout>

...
因此,现在我设置了setingsviewmodel的
Visible
-属性,但弹出按钮不会打开。我做错了什么



我只是尝试分配
IsOpen=“true”
硬编码,但这也不起作用。所以用数据模板显示弹出按钮似乎是个问题

我按照埃尔霍链接的问题讨论中的描述构建了它,现在它可以工作了。关键是在那里定义
ItemContainerStyle
并绑定
IsOpen

新的
main窗口.xaml

<controls:MetroWindow.Flyouts>
    <controls:FlyoutsControl ItemsSource="{Binding Flyouts}">
        <controls:FlyoutsControl.Resources>
            <view:FlyoutPositionConverter x:Key="FlyoutPositionConverter"/>
        </controls:FlyoutsControl.Resources>
        <controls:FlyoutsControl.ItemTemplate>
            <DataTemplate DataType="{x:Type viewModel:SettingsViewModel}">
                <view:SettingsFlyout/>
            </DataTemplate>
        </controls:FlyoutsControl.ItemTemplate>
        <controls:FlyoutsControl.ItemContainerStyle>
            <Style BasedOn="{StaticResource {x:Type controls:Flyout}}"
               TargetType="{x:Type controls:Flyout}">
                <Setter Property="Header"
                    Value="{Binding Header}" />
                <Setter Property="IsOpen"
                    Value="{Binding Visible}" />
                <Setter Property="Position"
                    Value="{Binding Position, Converter={StaticResource FlyoutPositionConverter}}" />
                <Setter Property="IsModal"
                    Value="{Binding IsModal}" />
                <Setter Property="Theme" Value="Accent" />
            </Style>
        </controls:FlyoutsControl.ItemContainerStyle>
    </controls:FlyoutsControl>
</controls:MetroWindow.Flyouts>
flyioutpositionconverter
只是我的位置枚举和
MahApps.Metro.Controls.position
之间的映射器,因为我不想在viewmodel界面中使用真实的位置


此外,视图现在不再需要是弹出型按钮,它可以是一个普通的用户控件。

如果在可见属性的设置器上调用PropertyChanged,则第一个解决方案也应该可以很好地工作

尝试将此
UpdateSourceTrigger=PropertyChanged,Mode=TwoWay
添加到IsOpen属性中如果我没有弄错,这是默认值,但是我会尝试显示
IFlyoutViewModel
的定义吗?我扩展了问题可能会有所帮助我在设置可见属性时调用PropertyChanged,并且绑定是否同时设置为TwoWay?我在mvvm环境中使用弹出按钮,就像您在开始时所描述的那样……我只是设置了IsOpen={Binding IsMenuOpen,Mode=TwoWay}并在我的ViewModel中设置了值是的,我手动设置了它,因为Eldho在注释中建议了它,但它不起作用-这并不奇怪,因为TwoWay是正常属性的默认值Shi Florian,您是否假设所有ViewModels只有一个用户控件显示为弹出型按钮?"". 如何使用MVVM为每个弹出按钮指定不同的UserControl。Thanks@Bill不可以,您可以有多个弹出型按钮-viewmodels存储在属性
弹出型按钮中,您可以为不同的视图指定多个数据模板。不过,在这种情况下,您必须使用ItemTemplateChooser。谢谢,但我不知道如何使用每个弹出按钮更改UserControl?正如您所说,弹出型按钮属性具有ViewModels而不是实际视图,如何更改视图?也许我在这里遗漏了什么。@Bill在我的例子中,视图是由ItemTemplate指定的。如果您希望能够拥有不同的模板(即不同的视图),则必须使用TemplateChooser。你可以用谷歌搜索这个,这是一个常见的问题approach@Bill这里TemplateChooser的思想是根据所显示的项的类型(在本例中是您的viewmodel)采用不同的DataTemplate
<controls:MetroWindow.Flyouts>
    <controls:FlyoutsControl ItemsSource="{Binding Flyouts}">
        <controls:FlyoutsControl.Resources>
            <view:FlyoutPositionConverter x:Key="FlyoutPositionConverter"/>
        </controls:FlyoutsControl.Resources>
        <controls:FlyoutsControl.ItemTemplate>
            <DataTemplate DataType="{x:Type viewModel:SettingsViewModel}">
                <view:SettingsFlyout/>
            </DataTemplate>
        </controls:FlyoutsControl.ItemTemplate>
        <controls:FlyoutsControl.ItemContainerStyle>
            <Style BasedOn="{StaticResource {x:Type controls:Flyout}}"
               TargetType="{x:Type controls:Flyout}">
                <Setter Property="Header"
                    Value="{Binding Header}" />
                <Setter Property="IsOpen"
                    Value="{Binding Visible}" />
                <Setter Property="Position"
                    Value="{Binding Position, Converter={StaticResource FlyoutPositionConverter}}" />
                <Setter Property="IsModal"
                    Value="{Binding IsModal}" />
                <Setter Property="Theme" Value="Accent" />
            </Style>
        </controls:FlyoutsControl.ItemContainerStyle>
    </controls:FlyoutsControl>
</controls:MetroWindow.Flyouts>
using System.ComponentModel;

namespace MyApplication.ViewModel
{
    internal interface IFlyoutViewModel : INotifyPropertyChanged
    {
        string Header { get; }
        bool Visible { get; set; }
        Position Position { get; set; }
        bool IsModal { get; set; }
    }

    public enum Position
    {
        Top,
        Left,
        Right,
        Bottom
    }
}