我在使用Caliburn Micro的Conductor<>.Collection.OneActive
與MahApps.Metro HamburgerMenu
有幾個問題。從fewsamples,但他們都沒有解決我的情況。用Caliburn Micro進行MahApps.Metro HamburgerMenu
我的代碼全部來自於this Github repository。我想顯示一組HamburgerMenu
裏面的一組窗格。每個窗格有一個標題和顯示名稱:
public interface IPane : IHaveDisplayName, IActivate, IDeactivate
{
PackIconModernKind Icon { get; }
}
在我的情況,IPane
使用PaneViewModel
實現:
public class PaneViewModel : Screen, IPane
{
public PaneViewModel(string displayName, PackIconModernKind icon)
{
this.Icon = icon;
this.DisplayName = displayName;
}
public PackIconModernKind Icon { get; }
}
這有以下幾種觀點:
<UserControl x:Class="CaliburnMetroHamburgerMenu.Views.PaneView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Padding="12"
Background="Pink">
<StackPanel Orientation="Vertical">
<TextBlock Text="Non-bound text" />
<TextBlock x:Name="DisplayName" FontWeight="Bold" />
</StackPanel>
</UserControl>
我的外殼視圖模型也相當簡單。它從Conductor<IPane>.Collection.OneActive
繼承,並採取了窗格的列表,它添加到其Items
集合:現在
public class ShellViewModel : Conductor<IPane>.Collection.OneActive
{
public ShellViewModel(IEnumerable<IPane> pages)
{
this.DisplayName = "Shell!";
this.Items.AddRange(pages);
}
}
,這是非常對我來說變得模糊。這是從ShellView.xaml
摘錄:
<controls:HamburgerMenu
ItemsSource="{Binding Items, Converter={StaticResource PaneListToHamburgerMenuItemCollection}}"
SelectedItem="{Binding ActiveItem, Mode=TwoWay, Converter={StaticResource HamburgerMenuItemToPane}}">
<ContentControl cal:View.Model="{Binding ActiveItem}" />
<controls:HamburgerMenu.ItemTemplate>
<DataTemplate>
<Grid x:Name="RootGrid"
Height="48"
Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<iconPacks:PackIconModern
Grid.Column="0"
Kind="{Binding Icon}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="White" />
<TextBlock Grid.Column="1"
VerticalAlignment="Center"
FontSize="16"
Foreground="White"
Text="{Binding Label}" />
</Grid>
</DataTemplate>
</controls:HamburgerMenu.ItemTemplate>
</controls:HamburgerMenu>
爲了使這項工作,我靠,兩個轉換器(誰坦率地說,做的比他們應該有)。一個轉換器採用ICollection<IPane>
,並創建一個HamburgerMenuItemCollection
與HamburgerMenuIconItem
,它們現在包含使用視圖模型和菜單項的Tag
屬性的雙向鏈接。
class PaneListToHamburgerMenuItemCollection : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var viewModels = value as ICollection<IPane>;
var collection = new HamburgerMenuItemCollection();
foreach (var vm in viewModels)
{
var item = new HamburgerMenuIconItem();
item.Label = vm.DisplayName;
item.Icon = vm.Icon;
item.Tag = vm;
vm.Tag = item;
collection.Add(item);
}
return collection;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
第二個轉換器視圖模型,並使用菜單項之間將這個Tag
每當SelectedItem
變化:
class HamburgerMenuItemToPane : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((IPane)value)?.Tag;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((HamburgerMenuIconItem)value)?.Tag;
}
}
當我運行此代碼,並單擊漢堡包菜單中的項目中,頁面切換每次。問題是,當應用第一次運行時,沒有選定的窗格,並且您不能使用ShellViewModel
中的任何激活覆蓋(例如OnViewAttached
或OnActivate
或事件構造函數)設置一個,因爲轉換器代碼掛鉤Tag
尚未運行。
我對工作的解決方案要求:
- 卡利的導線必須負責,因爲有意見和視圖模型進一步下跌依賴於激活邏輯來運行堆棧。
- 應該是可能的
ShellViewModel
- 激活期間在一些點以激活從卡利的第一項應該尊重的關注點分離,即視圖模型不應該知道,一個漢堡包菜單在視圖中被使用。
請參閱the GitHub repository瞭解應該立即運行的解決方案。
你設法找到一個解決方案或解決方法嗎? punker76或MahApps的其他人是否已挑選此問題? – pinowthebird
這將最終在v1.6.0中修復 – punker76