我刚刚开始在SL世界中尝试使用Caliburn NavigationShell作为我的起点。我将解决方案转换为SL4并从主干中使用Caliburn。
要创建基本导航,我有点不确定(好吧,相当),我如何将Buttons的原始StackPanel显示为可折叠的Treeview。
我将ITaskBarItem更改为拥有一个简单的GroupName属性
public interface ITaskBarItem : IEntryPoint
{
BitmapImage Icon { get; }
string DisplayName { get; }
string GroupName { get;}
}
然后,我在ShellViewModel中将它暴露给View:
public IEnumerable<IGrouping<string, ITaskBarItem>> TaskBarItems
{
get { return _taskBarItems.GroupBy(t => t.GroupName); }
}
如何进行xaml标记以便获得简单的层次结构?
如何在不使用按钮的情况下绑定Actions?
> GroupName DisplayName DisplayName DisplayName > GroupName DisplayName DisplayName DisplayName ...
介意,这是MVVM,所以我不打算使用代码或事件来做到这一点......
答案 0 :(得分:2)
这里有一些困难。首先,这是我的标记:
<ItemsControl x:Name="TaskBarItems">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Converter={StaticResource groupName}}"
FontWeight="Bold" />
<ItemsControl ItemsSource="{Binding}"
Margin="12 0 0 0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding DisplayName}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
和我的壳牌:
public class ShellViewModel : IShell
{
readonly TaskBarItemViewModel[] taskBarItems;
public ShellViewModel()
{
taskBarItems = new[]
{
new TaskBarItemViewModel {GroupName = "Animal", DisplayName = "Monkey"},
new TaskBarItemViewModel {GroupName = "Animal", DisplayName = "Cat"},
new TaskBarItemViewModel {GroupName = "Animal", DisplayName = "Dog"},
new TaskBarItemViewModel {GroupName = "Mineral", DisplayName = "Biotite"},
new TaskBarItemViewModel {GroupName = "Mineral", DisplayName = "Phlogopite"},
new TaskBarItemViewModel {GroupName = "Mineral", DisplayName = "Lepidolite"},
};
}
public IEnumerable<IGrouping<string, TaskBarItemViewModel>> TaskBarItems
{
get
{
return taskBarItems.GroupBy(t => t.GroupName).ToList();
}
}
}
Calibrun Micro(cm)将按照惯例绑定itemscontrol,TaskBarItems。但是,由于某些原因,其余部分不会按惯例运作。它位于DataTemplate中,因此我们通常使用Bind.Model。但是,它在这里不起作用,因为itemscontrol中每个项的类型是通用的(IGrouping)。默认约定无法处理为此查找视图。所以我们提供内联的数据模板。
其次,Key属性似乎是作为显式接口实现的。这意味着Silverlight无法绑定它。我做了一个简单的转换器,绑定到组并提取密钥:
public class GroupNameConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((IGrouping<string,TaskBarItemViewModel>)value).Key;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
接下来,由于分组本身就是IEnumerable,我们必须直接绑定嵌套itemscontrol的ItemsSource。我们不能使用约定,因为IGrouping上没有返回项的属性。 (虽然如果有的话,我们可能仍然会有明确的界面问题。)
关于你的第二个问题。您可以将操作绑定到任何事件。请参阅此处的文档: http://caliburnmicro.codeplex.com/wikipage?title=All%20About%20Actions&referringTitle=Documentation
答案 1 :(得分:1)
克里斯托弗答案中的价值转换器可以概括为:
public class ExplicitPropertyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value == null ? null : GetPropertyValue(value, (string)parameter);
}
private static object GetPropertyValue(object target, string name)
{
return (
from type in target.GetType().GetInterfaces()
from prop in type.GetProperties()
where prop.Name == name && prop.CanRead
select prop.GetValue(target, new object[0])
).FirstOrDefault();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
用法在这里:
<TextBlock
Text="{
Binding
Converter={StaticResource ExplicitPropertyConverter},
ConverterParameter=Key
}"
/>
此转换器支持任何接口的任何属性。有关my blog的更多信息。