代码之家  ›  专栏  ›  技术社区  ›  Jan

使用caliburn将sl4 treeview绑定到i组

  •  3
  • Jan  · 技术社区  · 16 年前

    我刚刚开始在SL世界,并试图使用Caliburn导航地狱作为我的起点。我把溶液转换成SL4,用后备箱里的Caliburn。

    要创建基本导航,我有点不确定(好吧,相当),如何将原来的按钮stackpanel显示为可折叠的treeview。

    我将itaskbaritem更改为拥有一个简单的groupname属性

    public interface ITaskBarItem : IEntryPoint
    {
        BitmapImage Icon { get; }
        string DisplayName { get; }
        string GroupName { get;}
    }
    

    然后,我在ShellViewModel中将其公开到视图中:

        public IEnumerable<IGrouping<string, ITaskBarItem>> TaskBarItems
        {
            get { return _taskBarItems.GroupBy(t => t.GroupName); }
        }
    

    如何进行xaml标记以便获得简单的层次结构?

    如何在不使用按钮的情况下绑定操作?

    > GroupName
        DisplayName
        DisplayName
        DisplayName
    
    > GroupName
        DisplayName
        DisplayName
        DisplayName
        ...
    

    注意,这是mvvm,所以我不打算使用代码隐藏或事件来完成…

    2 回复  |  直到 15 年前
        1
  •  2
  •   Christopher Bennage    16 年前

    这里有几个困难。首先,这是我的标记:

    <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)将按惯例绑定项控件taskBaritems。然而,由于一些原因,其余的将不能按惯例工作。它在数据模板中,所以我们通常使用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

        2
  •  1
  •   serega    15 年前

    克里斯托弗答案中的值转换器可以概括如下:

    
    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 .