16

我正在尝试使 WPF 组合框正常工作(在 WPFToolkit Datagrid 内),但我无法正确对齐所有部分。我正在使用 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 的位置。此时,显示的值将恢复为原始值,而不是新选择的值。我尝试使用 SelectedItem 而不是 SelectedValue,但最终选择的值未显示在 ComboBox 中。我有点迷惑:似乎这点应该起作用。

2009 年 3 月 2 日编辑:我仍然对此感到困惑。我应该注意,在我的数据网格中,任何简单的数据列(例如,“DataGridTextColumn”)都会按照您的预期更新基础数据源。但是对我的任何模板列(“DataGridTemplateColumn”)或 ComboBox 列(“DataGridComboBoxColumn”)的任何更新都不起作用:基础数据源永远不会更新。当然其他人已经尝试使用 WPF.Toolkit 数据网格并让这个场景工作 - 但我已经查看了那里的所有示例代码,并且我基本上按照它所说的去做(在我的约束范围内)解决方案),所以我在摸索为什么这不起作用。

有什么想法吗?

4

3 回答 3

25

我有一个类似的问题(我花了几天的时间沮丧),我发现更改绑定以UpdateSourceTrigger修复它。我不知道为什么,但对我来说,直到我做出这个改变,数据源才被更新。SelectedValuePropertyChanged

<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. 我创建了一个 ViewModel 作为与 View 的合同。
  2. 我绑定到 ComboBox.SelectedItem 属性而不是 ComboBox.SelectedValue 属性

由于我不知道您的数据源是什么,所以我自己编写了一个来模拟基本问题:在 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;
        }
    }
}

在开始之前,我将 Window 的 DataContext 设置为我正确构造的 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 正确绑定,我需要确保我已经覆盖了我的实体上的 Equals 方法,因为在后台,WPF 正在使用此方法来确定谁是 SelectedItem。我认为这从根本上是您从一开始就导致您尝试绑定到 SelectedValue 而不是 SelectedItem 的问题。

于 2009-03-20T05:39:34.357 回答
0

您需要添加

IsSynchronizedWithCurrentItem = "True"

在您的 Xaml 中。

就这么简单...

于 2011-07-12T09:08:44.553 回答