WPFコンボボックスはソースを更新しません
-
09-09-2019 - |
質問
WPFコンボボックスを動作させようとしています(WPFTOOLKIT DATAGRID内)。すべてのピースを正しく整列させるのに苦労しています。私はlinqをエンティティに使用していますが、全体的なdataContextをlinqクエリの結果に設定しています。
private void LoadDonationGrid()
{
donationGrid.ItemsSource = from donations in entities.Donation
.Include("Family")
.Include("PledgeYear")
.Include("DonationPurpose")
from donationPurposes in entities.DonationPurpose
select new { donations, donationPurposes };
}
また、Code-Behindにページプロパティがあり、コンボボックスのアイテムソースを提供しています。
private IEnumerable donationPurposeList;
public IEnumerable DonationPurposeList
{
get
{
if (donationPurposeList == null)
{
donationPurposeList = from dp in entities.DonationPurpose
select dp;
}
return donationPurposeList.ToList();
}
}
コンボボックスのXAMLは次のようになります:
<tk:DataGridTemplateColumn Header="Purpose">
<tk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=donations.DonationPurpose.Description, Mode=TwoWay}" />
</DataTemplate>
</tk:DataGridTemplateColumn.CellTemplate>
<tk:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox Name="cboDonationPurpose"
SelectedValue="{Binding Path=donations.DonationPurposeID, Mode=TwoWay}"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type Page},Mode=FindAncestor},Path=DonationPurposeList}"
DisplayMemberPath="Description"
SelectedValuePath="DonationPurposeID"
/>
</DataTemplate>
</tk:DataGridTemplateColumn.CellEditingTemplate>
</tk:DataGridTemplateColumn>
そして、すべてが正しく機能しているように見えます。つまり、適切な値はコンボボックスに表示されます。その時点で、表示された値は、新しく選択された値ではなく、元の値に戻ります。 selectedValueの代わりにselectedItemを使用してみましたが、コンボボックスに表示されない選択された値になります。私はちょっと神秘的です:このビットが機能しているはずです。
編集3/2/09:私はまだこれを困惑させています。 Datagridでは、シンプルなデータ列(「DatagridTextColumn」など)は、予想通り基礎となるデータソースを更新することに注意してください。しかし、私のテンプレート列(「datagridtemplatecolumn」)またはコンボボックス列(「datagridcomboboxcolumn」)のいずれかの更新は機能しません:基礎となるデータソースが更新されることはありません。確かに他の人々はwpf.toolkit datagridを使用しようとし、このシナリオを機能させようとしましたが、私はそこにあるすべてのサンプルコードを見てきました。解決策)、だから私はなぜこれが機能していないのか頭を掻いています。
何かご意見は?
解決
私は同様の問題を抱えていました(私はフラストレーションの日を何日も費やしました)、そして私は変化することがわかりました UpdateSourceTrigger
に SelectedValue
に結合します PropertyChanged
修正しました。理由はわかりませんが、私にとっては、この変更を加えるまでデータソースは更新されていませんでした。
<ComboBox
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UpdateTypesManager:MainWindow}}, Path=CardinalityTypes}"
DisplayMemberPath="CardinalityType"
SelectedValue="{Binding CardinalityTypeId, UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="Id" />
他のヒント
私はこれを機能させることができました。しかし、私は物事を少し違った方法で設定します。
- ビューとの契約として機能するViewModelを作成しました。
- combox.selectedvalueプロパティの代わりにcombobox.selectedItemプロパティに縛られています
あなたのデータソースが何であるかわからなかったので、基本的な問題をシミュレートするために自分で構成しました。WPFデータグリッド内でコンボボックスを正しくバインドすることです。
これが私のビューモデルの構成です:
public class RootViewModel
{
public List<State> USStates { get; set; }
public List<Customer> Customers { get; set; }
public ViewModel()
{
Customers = new List<Customer>();
Customers.Add(new Customer() { FirstName = "John", LastName = "Smith", State = new State() { ShortName = "IL" } });
Customers.Add(new Customer() { FirstName = "John", LastName = "Doe", State = new State() { ShortName = "OH" } });
Customers.Add(new Customer() { FirstName = "Sally", LastName = "Smith", State = new State() { ShortName = "IN" } });
USStates = new List<State>();
USStates.Add(new State() { ShortName = "OH" });
USStates.Add(new State() { ShortName = "IL" });
USStates.Add(new State() { ShortName = "IN" });
}
}
public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
public State State { get; set; }
}
public class State
{
public string ShortName { get; set; }
public State()
{
ShortName = string.Empty;
}
public override bool Equals(object obj)
{
if (obj is State)
{
State otherState = obj as State;
return ShortName.Equals(otherState.ShortName);
}
else
{
return false;
}
}
}
開始する前に、ウィンドウのデータコンテキストを適切に構築されたrootViewModelのインスタンスに設定します。
<tk:DataGrid ItemsSource="{Binding Customers}" AutoGenerateColumns="False">
<tk:DataGrid.Columns>
<tk:DataGridTemplateColumn Header="State">
<tk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=State.ShortName, Mode=TwoWay}" />
</DataTemplate>
</tk:DataGridTemplateColumn.CellTemplate>
<tk:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox
x:Name="cboDonationPurpose"
SelectedItem="{Binding Path=State, Mode=TwoWay}"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window},Mode=FindAncestor}, Path=DataContext.USStates}"
DisplayMemberPath="ShortName"
SelectedValuePath="ShortName" />
</DataTemplate>
</tk:DataGridTemplateColumn.CellEditingTemplate>
</tk:DataGridTemplateColumn>
</tk:DataGrid.Columns>
</tk:DataGrid>
SelectedItemが適切にバインドするためには、ボンネットの下では、WPFがこの方法を使用してSelectedItemのかどうかを判断するために、エンティティの等しい方法をオーバーライデンにしていることを確認する必要があります。これは根本的に最初からあなたの問題であり、SelectedItemの代わりにSelectedValueにバインドしようとしたと思います。
追加する必要があります
IsSynchronizedWithCurrentItem = "True"
あなたのxamlで。
それはそれと同じくらい簡単です...