【问题标题】:Datagrid combobox disappearing content + autocompleteDatagrid组合框消失的内容+自动完成
【发布时间】:2020-01-11 07:51:20
【问题描述】:

从昨天开始,我一直在尝试解决这个问题,但没有任何成功(谷歌搜索)。我在DataGridTemplateColumn 中有一个组合框,当我选择某些内容然后单击另一个单元格时,组合框的内容消失了,但是当再次单击时仍然存在。向下滚动数据网格时,情况类似。

我几乎尝试了我在网上找到的所有东西,但没有任何成功。我不明白为什么会这样。

当我切换到DataGridComboboxColumn 时,一切正常,但在这种情况下我无法实现可搜索(自动完成)组合框。

我在 xaml 中的组合框如下所示:

<DataGrid ItemsSource="{Binding ListOfCars}"
          SelectedItem="{Binding SelectedCar, Mode=TwoWay}"               
    <DataGridTemplateColumn Header="Type">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <ComboBox
                    Width="150"
                    IsEditable="True"
                    IsDropDownOpen="False"
                    ItemsSource="{Binding Source={StaticResource TypeLists}}"
                    DisplayMemberPath="Type"
                    SelectedValuePath="IDType"
                    SelectedItem="{Binding SelectedType}"                              
                    SelectedValue="{Binding IDType, 
                                            Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                    IsReadOnly="False"
                    IsSynchronizedWithCurrentItem="False">
                </ComboBox>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
</DataGrid>

SelectedCarCar 类型,ListOfCarsList&lt;Car&gt; 类型 SelectedValue (IDType) 是 Car 类中的一个属性。

我想实现两件事:

  1. 选中后,即使我单击其他单元格,组合框中的项目也会保留。
  2. 有没有简单的方法来实现自动完成组合框? (我尝试使用DotNetKit.Wpf.AutoCompleteComboBox,但在 datagrid 外部它的工作原理就像一个魅力,但内部情况与组合框相同......)

【问题讨论】:

  • 单元格模板的数据上下文是 Car(Car 类),因此此类必须包含属性 SelectedType 才能工作。是这样的吗?
  • Car 类包含 IDType 并且 SelectedValue 绑定到此属性

标签: c# wpf combobox datagrid datatemplate


【解决方案1】:

关于第一个问题,我复制了您的案例,并做了一些更改。它对我来说很好(Win10 VS pro 2019 .Net 4.7.2)。希望你能在那里找到答案。

我创建了你的课程

public class Car
{
    public int IDType { get; set; }
}

public class Type
{
    public string Name { get; set; }
    public int IDType { get; set; }

}

我用一些示例创建了一个视图模型

class ViewModel
{
    public List<Car> ListOfCars { get; set; }
    public Car SelectedCar { get; set; }
    public List<Type> TypeLists { get; set; }


    public ViewModel()
    {
        // Add five cars
        ListOfCars = new List<Car>();
        for (int i = 0; i < 5; i++)
        {
            ListOfCars.Add(new Car());
        }

        // Add three types: type0, type1, type2
        TypeLists = new List<Type>();
        for (int i = 0; i < 3; i++)
        {
            TypeLists.Add(new Type() { Name = $"type{i}", IDType = i });
        }
    }
}

对于视图,我使用了主窗口

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewModel();
    }
}

我在主窗口 XAML 中添加了数据网格,并对我的视图模型进行了一些更改。如果使用 UserControl,请在下面的代码中将 AncestorType 更改为 UserControl。

<DataGrid 
        ItemsSource="{Binding ListOfCars}"
        SelectedItem="{Binding SelectedCar, Mode=TwoWay}" >
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="Type">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox
                            Width="150"
                            IsEditable="True"
                            IsDropDownOpen="False"
                            ItemsSource="{Binding 
                                Path = DataContext.TypeLists, 
                                RelativeSource={RelativeSource FindAncestor, 
                                AncestorType=Window}}"
                            DisplayMemberPath="Name"
                            SelectedValuePath="IDType"                                                           
                            SelectedValue="{Binding IDType, 
                                        Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                            IsReadOnly="False"
                            IsSynchronizedWithCurrentItem="False">
                        </ComboBox>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>

我得到下表,左列是绑定到 TypeLists 的组合框,右列是自动生成的 Car IDType。

我更改了一些组合框,然后滚动,一切就位。

根据经验,数据从窗口/用户控件中消失的原因有两个:错误绑定和空值注入属性。

当绑定错误时,数据不会被存储,任何刷新的窗口都会消失。在调试模式下检查 VS 的输出窗口,它会为您提供有关绑定损坏的信息。

有时在导航页面时会将 null 注入到属性中。这可以通过在有问题的属性的设置器中添加以下行来避免:

if (value==null) return

【讨论】:

  • 非常感谢您的回答。我无法复制它,因为ItemsSource="{Binding Path = DataContext.TypeLists, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"在我的情况下不起作用。我需要使用ItemsSource="{Binding Source={StaticResource TypeLists}}" 替换它。也许是因为我使用 IoC 容器和 ServiceLocator 在 xaml 文件中实例化 DataContext。如果您滚动数据网格时组合框值消失,您能否写下?谢谢
  • 它就像一个魅力。我还有一个问题:当我使用 DataAnnotations 和 IDataErrorInfo 验证行时,我需要先单击任何其他单元格,否则当从组合框中选择某项然后单击其他单元格时,组合框内容会消失。如何解决?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-10
  • 2011-07-31
  • 1970-01-01
  • 1970-01-01
  • 2011-08-07
相关资源
最近更新 更多