Wpf DataGridTemplateColumn和ComboBox作为CellEditingTemplate发生意外更改

时间:2014-05-14 07:32:04

标签: c# wpf combobox wpfdatagrid

以下是展示我们实际问题的演示项目。

假设我们有以下数据:

public class Person
{
    public PersonType PersonType { get; set; }
    public Job Job { get; set; }
}

public class PersonType
{
    public string Name { get; set; }
    public List<Job> Jobs { get; set; }
}

public class Job
{
    public string Name { get; set; }
}

和样本数据:

public class TestData
{
    public static List<PersonType> PersonTypes = new List<PersonType>
    {
        new PersonType
        {
            Name = "Person1",
            Jobs = new List<Job>
            {
                new Job{Name = "Development"},
                new Job{Name = "Testing"}
            }
        },
        new PersonType
        {
            Name = "Person2",
            Jobs = new List<Job>
            {
                new Job{Name = "Design"},
                new Job{Name = " Analysis"}
            }
        }
    };
}

现在我们有一个用于查看和管理数据的数据网格:

<Window.Resources>
    <CollectionViewSource x:Key="People" />
    <CollectionViewSource x:Key="PersonTypes" />
    <CollectionViewSource x:Key="JobsData" />
</Window.Resources>
<DataGrid ItemsSource="{Binding Source={StaticResource People}}" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTemplateColumn>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding PersonType.Name}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <ComboBox SelectedValue="{Binding PersonType, UpdateSourceTrigger=PropertyChanged}" 
                                        ItemsSource="{Binding Source={StaticResource PersonTypes}}" 
                                        DisplayMemberPath="Name" SelectionChanged="PersonTypeChanged" IsSynchronizedWithCurrentItem="False" />
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
        </DataGridTemplateColumn>
        <DataGridTemplateColumn>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Job.Name}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding Source={StaticResource JobsData}}"
                                        DisplayMemberPath="Name" SelectedValue="{Binding Job}" IsSynchronizedWithCurrentItem="False" />
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
        People.Source = new List<Person>();
        PersonTypes.Source = TestData.PersonTypes;
    }

    public CollectionViewSource People { get { return Resources["People"] as CollectionViewSource; } }
    public CollectionViewSource PersonTypes { get { return Resources["PersonTypes"] as CollectionViewSource; } }
    public CollectionViewSource JobsData { get { return Resources["JobsData"] as CollectionViewSource; } }

    private void PersonTypeChanged(object sender, SelectionChangedEventArgs e)
    {
        var personType = (sender as ComboBox).SelectedItem as PersonType;
        if (personType == null)
        {
            JobsData.Source = null;
        }
        else
        {
            JobsData.Source = personType.Jobs;
        }
    }
}

简而言之,当为PersonType行选择Person时,Job列应填充PersonType可供选择的作业。< / p>

现在的问题是:当我们更改“人物类型”时连续,其他行的作业将受到影响(过滤)。似乎CellEditingTemplate不仅适用于编辑模式,它仍然存在且功能正常,但未显示。因此,当ItemsSource的{​​{1}}发生更改时,它会影响所有行。

我们如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

这种情况正在发生,因为您对所有行使用相同的JobsData CollectionViewSource。如果您不想更改设计,我建议缓存单元格编辑事件并在那里更新JobsData。