Metro Flyouts with MVVM

匿名 (未验证) 提交于 2019-12-03 01:36:02

问题:

I'm trying to use the Flyouts from MahApps.Metro in my application. So I added this part to my 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> 

The ItemTemplate will contain the mappings from my viewmodels to the views. Flyouts is an ObservableCollection<IFlyoutViewModel> and currently only contains my SettingsViewModel.

The IFlyoutViewModel definition:

using System.ComponentModel;  namespace MyApplication.ViewModel {     internal interface IFlyoutViewModel : INotifyPropertyChanged     {         bool Visible { get; set; }     } } 

And how I use the Visible-property:

<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> 

So now I set the Visible-property of my SettingsViewModel, but the Flyout won't open. What am I doing wrong?


I just tried to assign IsOpen="true" hardcoded but this didn't work, too. So displaying the flyout with a datatemplate seems to be the problem...

回答1:

I built it like described in the issue dicussion linked by Eldho, now it works. The key ist to define ItemContainerStyle and bind IsOpen there!

The new MainWindow.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> 

The new IFlyoutViewModel:

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

The FlyoutPositionConverter is just a mapper between my position enum and the MahApps.Metro.Controls.Position because I didn't want to use the real positon in my viewmodel interface.

Also the view now no longer needs to be a Flyout, it can be a normal usercontrol.



回答2:

Your first solution also should work well if you call OnPropertyChanged on the Setter of your Visible-Property



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!