16

(WPFToolkit Datagrid 内で) WPF コンボボックスを動作させようとしていますが、すべてのピースを正しく配置するのに問題があります。私は Linq to Entities を使用しており、データコンテキスト全体を 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 };
}

コード ビハインドには、コンボ ボックスの ItemsSource を提供するページ プロパティもあります。


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>

そして、すべてが正しく機能しているように見えます。つまり、フォーカスが ComboBox を離れるポイントまで、適切な値が ComboBox に表示されます。その時点で、表示値は、新しく選択した値ではなく、元の値に戻ります。SelectedValue の代わりに SelectedItem を使用してみましたが、選択した値が ComboBox に表示されなくなります。私はちょっと当惑しています: このビットは機能するはずです。

2009 年 3 月 2 日編集: 私はまだこれについて困惑しています。私のデータ グリッドでは、単純なデータ列 ("DataGridTextColumn" など) が、期待どおりに基になるデータ ソースを更新することに注意してください。しかし、テンプレート化された列 ("DataGridTemplateColumn") または ComboBox 列 ("DataGridComboBoxColumn") の更新は機能しません。基になるデータ ソースは更新されません。確かに、他の人々が WPF.Toolkit データグリッドを使用しようとして、このシナリオが機能するようになりました。解決策)、なぜこれが機能しないのか頭を悩ませています。

何かご意見は?

4

3 に答える 3

25

私は同様の問題を抱えていました(何日もフラストレーションを感じていました)がUpdateSourceTriggerSelectedValueバインディングの を変更してPropertyChanged修正したことがわかりました。理由はわかりませんが、この変更を行うまでデータソースは更新されませんでした。

<ComboBox 
    ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UpdateTypesManager:MainWindow}}, Path=CardinalityTypes}" 
    DisplayMemberPath="CardinalityType"
    SelectedValue="{Binding CardinalityTypeId, UpdateSourceTrigger=PropertyChanged}"
    SelectedValuePath="Id" />
于 2011-02-18T01:17:58.060 に答える
6

これを機能させることができました。しかし、私は物事を少し違った方法で設定しました。

  1. View とのコントラクトとして機能する ViewModel を作成しました。
  2. ComboBox.SelectedValue プロパティではなく、ComboBox.SelectedItem プロパティにバインドしました

私はあなたのデータ ソースが何であるかを知らなかったので、基本的な問題をシミュレートするために独自に作成しました: WPF DataGrid 内でコンボ ボックスを正しくバインドすることです。

これが私のビューモデルの構成です:

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 のインスタンスになるように、Window の DataContext を設定します。

<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 を適切にバインドするには、エンティティの Equals メソッドをオーバーライドしたことを確認する必要があります。これは、WPF がこのメソッドを使用して、誰が SelectedItem であるかどうかを判断しているためです。これは根本的にあなたの問題であり、SelectedItem ではなく SelectedValue にバインドしようとした原因だと思います。

于 2009-03-20T05:39:34.357 に答える
0

追加する必要があります

IsSynchronizedWithCurrentItem = "True"

Xamlで。

それはそれと同じくらい簡単です...

于 2011-07-12T09:08:44.553 に答える