3

SL の世界を始めたばかりで、Caliburn NavigationShell を出発点として使用しようとしています。ソリューションを SL4 に変換し、トランクから Caliburn を使用します。

基本的なナビゲーションを作成するには、ボタンの元の StackPanel を折りたたみ可能な Treeview として表示する方法が少しわかりません (かなり)。

単純な GroupName プロパティを所有するように ITaskBarItem を変更しました

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 マークアップを行うにはどうすればよいですか?

ボタンを使用せずにアクションをバインドするにはどうすればよいですか?

> グループ名
    表示名
    表示名
    表示名

> グループ名
    表示名
    表示名
    表示名
    ...

これはMVVMなので、コードビハインドやイベントを使用するつもりはありません...

4

2 に答える 2

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 であるため、ネストされた項目コントロールの ItemsSource を直接バインドする必要があります。IGrouping には項目を返すプロパティがないため、規則を使用できません。(もしあったとしても、おそらく明示的なインターフェースの問題がまだ残っているでしょう。)

2番目の質問について。アクションを任意のイベントにバインドできます。こちらのドキュメントを参照してください: http://caliburnmicro.codeplex.com/wikipage?title=All%20About%20Actions&referringTitle=Documentation

于 2010-09-08T15:06:44.907 に答える
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
    }"
    />

このコンバーターは、任意のインターフェースの任意のプロパティをサポートします。私のブログでより多くの情報。

于 2011-01-18T10:59:14.507 に答える