我正在开发一个新的WPF应用程序,它将大量使用Caliburn Micro(2.x),Telerik WPF套件。我在从另一个WPF项目开始创建,该项目使用了前面的两个组件(它使用CM 1.5.2),但我想让事情变得正确,避免过去所做的变通方法
在这两个应用程序中,我都使用了Valeriu Caraulean开发的Telerik约定
主要思想是有一个带有RadDocking的顶层菜单,用于停靠这些项
这是WorkSpaceViewModel
public class WorkSpaceViewModel : Conductor<object>.Collection.OneActive, IHandle<MenuMessage>
{
#region Variables
private readonly IDockManager dockManager;
private readonly IEventAggregator eventAggregator;
#endregion
#region Properties
public MenuViewModel Menu { get; set; }
#endregion
public WorkSpaceViewModel(MenuViewModel menu, IDockManager dockManager, IEventAggregator eventAggregator)
{
this.dockManager = dockManager;
this.eventAggregator = eventAggregator;
eventAggregator.Subscribe(this);
Menu = menu;
}
protected override void OnViewLoaded(object view)
{
base.OnViewLoaded(view);
dockManager.Link(this);
Menu.GenerateMenu();
}这是WorkSpaceView
<Grid.RowDefinitions>
<RowDefinition x:Name="rowMenu" Height="Auto" MinHeight="30"/>
<RowDefinition x:Name="rowDocking" Height="*"/>
<!-- Height="Auto" -->
</Grid.RowDefinitions>
<Grid Grid.Row="0" Background="#FFF1F5FB">
<!-- Background="#FFF0F0F0"-->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<!--<ColumnDefinition Width="100"></ColumnDefinition>-->
</Grid.ColumnDefinitions>
<StackPanel>
<!--<ContentControl x:Name="Menu" cal:Bind.Model="{Binding Menu}"></ContentControl>-->
<local:MenuView x:Name="Menu" cal:Bind.Model="{Binding Menu}" ></local:MenuView>
<!--cal:Bind.Model="{Binding Menu}"-->
</StackPanel>
<Border BorderThickness="0.5" CornerRadius="7" cal:Action.Target="{Binding}" BorderBrush="DarkGray" Background="#FFEFF7FC"
VerticalAlignment="Center" HorizontalAlignment="Right" Grid.Column="1" MaxWidth="200">
<telerik:RadExpander IsExpanded="False" VerticalContentAlignment="Top" telerik:AnimationManager.IsAnimationEnabled="True" ExpandDirection="Left">
<telerik:RadExpander.Content>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5,5,5,5">
<TextBlock x:Name="LoggedUser" Background="Transparent" FontStyle="Italic" FontSize="11" Margin="0,0,10,0">
<TextBlock.ContextMenu>
<ContextMenu>
<!--<telerik:RadMenuItem Header="Opzioni" cal:Message.Attach="[Event Click] = [Action OpenOptions($eventArgs)]"/>-->
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
<!--<Image cal:Message.Attach="[Event PreviewMouseDown] = [Action ShowInfo()]" cal:Action.TargetWithoutContext="{Binding}"
Width="14" Height="14">
<Image.Source>
<BitmapImage UriSource="/DOME;component/Media/info.png"></BitmapImage>
</Image.Source>
</Image>-->
</StackPanel>
</telerik:RadExpander.Content>
</telerik:RadExpander>
</Border>
</Grid>
<telerik:RadDocking Grid.Row="1" Background="{Binding WorkspaceBackground}" x:Name="docking" cal:Message.Attach="[Event ElementLoading] = [Action DockingLoading($eventArgs)]" >
<telerik:RadDocking.DocumentHost >
<telerik:RadSplitContainer ItemsSource="{Binding ModuleRadPaneGroups}" telerik:RadDocking.SerializationTag="splitContainer" VerticalContentAlignment="Stretch">
</telerik:RadSplitContainer>
</telerik:RadDocking.DocumentHost>
</telerik:RadDocking>
</Grid>这是MenuViewModel
public class MenuViewModel : Screen
{
#region Variables
private readonly IEventAggregator eventAggregator;
#endregion
#region Properties
private List<VisualMenuItem> items;
public List<VisualMenuItem> Items
{
get
{
return items;
}
set
{
items = value;
NotifyOfPropertyChange(() => Items);
}
}
public void GenerateMenu()
{
var menu = new List<VisualMenuItem>();
menu.Add(new VisualMenuItem { Text = "Calendario", Tag = "calendario" });
Items = menu;
}和MenuView
<Grid>
<Grid.Resources>
<BooleanToVisibilityConverter x:Key="booleanConverter" />
<HierarchicalDataTemplate x:Key="MenuItemTemplate" ItemsSource="{Binding Items}" >
<TextBlock Text="{Binding Text}" cal:Action.TargetWithoutContext="{Binding}"
Visibility="{Binding IsVisible,Mode=TwoWay,Converter={StaticResource booleanConverter}}" />
</HierarchicalDataTemplate>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition MinHeight="30"></RowDefinition>
</Grid.RowDefinitions>
<telerik:RadMenu x:Name="MenuList" ClickToOpen="False" BorderBrush="Transparent" ItemsSource="{Binding Menu.Items}" ItemTemplate="{StaticResource MenuItemTemplate}"
cal:Message.Attach="[Event ItemClick] = [Action OpenView($eventArgs)]" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
<telerik:RadMenu.ItemContainerStyle>
<Style TargetType="telerik:RadMenuItem">
<Setter Property="IsSeparator" Value="{Binding IsSeparator}" />
<Setter Property="IsChecked" Value="{Binding IsChecked, Mode=TwoWay}" />
<Setter Property="IsCheckable" Value="{Binding IsCheckable}" />
<Setter Property="StaysOpenOnClick" Value="{Binding IsCheckable}" />
<Setter Property="cal:Message.Attach" Value="[Event SubmenuOpened] = [Action SubMenuOpen($source)]" />
</Style>
</telerik:RadMenu.ItemContainerStyle>
</telerik:RadMenu>
</Grid>VisualMenuItem被定义为
public class VisualMenuItem : ObservableCollection<VisualMenuItem>
{
public Dictionary<string, object> MenuParameter { get; set; }
public int ID { get; set; }
public string Tag { get; set; }
public string ViewModelName { get; set; }
public Type ViewModelType { get; set; }
public int Position { get; set; }
public string Text { get; set; }
public string GroupName { get; set; }
public bool StaysOpenOnClick { get; set; }
public bool IsEnabled { get; set; }
public bool IsVisible { get; set; }
}当应用程序加载时,没有菜单...在上一个版本的WorkSpaceView中,我是这样做的
<local:MenuView x:Name="Menu" cal:Bind.Model="{Binding Menu}" ></local:MenuView>但是我读到在2.0中不推荐使用cal:Bind.Model="xxx“,而且我也避免在里面放一个视图,我更喜欢把ContentControl x:Name=放在”Menu“中。
我希望做的另一件事是在登录后加载菜单,以便在授权时过滤菜单项...在旧项目中,我隐藏了不允许的项,但它不是很好
有什么建议吗?谢谢
发布于 2015-02-28 12:18:41
<ContentControl x:Name="Menu" />应该可以很好地处理您所拥有的代码。您已经按原样注入了MenuViewModel ...但是当你实例化的时候,我会给它一个通知调用。cal:Bind.Model不是必需的,因为MenuView控件将使用您正在注入的MenuView模型的MenuView……ALso,这就像同时使用ViewFirst和ViewModelFirst一样。
public MenuViewModel Menu { get{ return menu ;} set{ menu = value; NotifyOnPropertyChange(); } }
https://stackoverflow.com/questions/28740815
复制相似问题