3

私たちは Caliburn.Micro/Silverlight 4 を使用しており、生活は良好です。

コンボボックスの itemsSource を viewModel にバインドしようとしていますが、コンボボックスが既に独自の行の dataItem にバインドされているため、これは不可能のようです。コンボを埋めるロジックは、画面上の他のデータで変化するため、これまで使用していたような静的リストは実際には使用できません。

ディレクトリをviewModelにバインドする方法はありますか??? 要素間のバインディングを試みましたが、これはグリッド内で機能するようには見えません。

       <Controls:DataGridTemplateColumn x:Name="FooNameCol" Header="Foo" MinWidth="200">
            <Controls:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>

                    <StackPanel>
                        <TextBlock Text="{Binding Path=Foo.ShortName}" 
                                   Style="{StaticResource DataGridTextColumnStyle}"/>
                    </StackPanel>

                </DataTemplate>
            </Controls:DataGridTemplateColumn.CellTemplate>
            <Controls:DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>

                    <ComboBox DisplayMemberPath="ShortName"   
                              MinWidth="200" MinHeight="25"
                              SelectedItem="{Binding Path=Officer, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}"
                              ItemsSource="{Binding Officers, Source={StaticResource ReferenceListRetriever}}" />

                </DataTemplate>
            </Controls:DataGridTemplateColumn.CellEditingTemplate>
        </Controls:DataGridTemplateColumn>
4

1 に答える 1

4

DataTemplate 内で、DataContext は対応するリストの各項目にバインドされます。すべての Binding は暗黙的に DataContext を参照するため、単一のデータ項目から始まるパスが有効であることを確認する必要があります。

あなたのシナリオでは、指定されたバインディングが機能するためには、VM を次のように構成する必要があります。

public class MyVM {
   public IEnumerable<MyItem> Items {get;}
}

public class MyItem {
  public Foo Foo {get;}
  public Officer Officer {get;set;}
  public IEnumerable<Officer> Officers {get;}
}

やり過ぎに思えるかもしれませんが、いくつかのシナリオでは、ビジネス ルールに基づいて、実際には各コンボにデータ項目ごとに異なる選択肢が含まれる場合があります。単純なケースでは、MyItem は親 MyVM からの共通リストを公開するだけです。

public class MyItem {
  ...
  public IEnumerable<Officer> Officers {
    get { return _parent.AvailableOfficers; }
  }
}

本当にそれを受け入れることができず、使用可能なオフィサーのリストをルート VM のみに保持したい場合は、Xaml のサイド トリックを使用できます。

public class MyVM {
  public IEnumerable<MyItem> Items {get;}
  public IEnumerable<Officer> Officers {get;}
}

public class MyItem {
  public Foo Foo {get;}
  public Officer Officer {get;set;}
}

Xaml:

<UserControl ...>
  ...
  <AnyFrameworkElementAtThisLevel Name="bridge" />
  ...
  <Controls:WhateverGrid>
     ...
     <Controls:DataGridTemplateColumn ...>
        <Controls:DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
              ...
            </DataTemplate>
        </Controls:DataGridTemplateColumn.CellTemplate>
        <Controls:DataGridTemplateColumn.CellEditingTemplate>
            <DataTemplate>
                <ComboBox DisplayMemberPath="ShortName"   
                          SelectedItem="{Binding Path=Officer, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}"
                          ItemsSource="{Binding DataContext.Officers, ElementName=bridge}" />

            </DataTemplate>
于 2010-10-30T16:24:31.810 に答える