【问题标题】:WPF Datagrid binding to list problemsWPF Datagrid 绑定以列出问题
【发布时间】:2010-01-25 01:04:38
【问题描述】:

我有一个自定义对象的列表:比如 Fruits 具有两个字符串属性 Name 和 Color。这些都在一个列表中。

private readonly List<Fruit> fruitList = new List<Fruit>();

然后我将水果对象加载到列表中。

我正在尝试将此列表绑定到 WPF Datagrid:

C#:

dgFruit.ItemsSource = "{Binding}";

XAML:

<toolkit:DataGrid Name="dgFruit" 
            ItemsSource="{Binding Path=fruitList}" >
                <toolkit:DataGrid.Columns>

                    <toolkit:DataGridComboBoxColumn 
            Header="Name" 
            SelectedValueBinding="{Binding Path=Name}" 
            TextBinding="{Binding Path=Name}" Width="5*" />   

                    <toolkit:DataGridComboBoxColumn 
            Header="Color"
            SelectedValueBinding="{Binding Path=Color}"
            TextBinding="{Binding Path=Color}" Width="5*" />

                </toolkit:DataGrid.Columns>
            </toolkit:DataGrid>

他们在组合框中的原因是因为我希望用户能够更改关系。这不是真实的例子,但你明白了。举例来说,水果没有成熟,所以他们把香蕉颜色变成绿色:)

我没有任何运气在数据网格中获取这些项目......并且沿着轨道,我希望单击数据网格单元中的项目以更改为组合框并显示所有可能类型的水果名称和颜色(所以他们可以改变关系)

这是我遇到的错误:

System.Windows.Data Error: 39 : BindingExpression path error: 'Color' property not found on 'object' ''Char' (HashCode=6750311)'. BindingExpression:Path=Color; DataItem='Char' (HashCode=6750311); target element is 'TextBlockComboBox' (Name=''); target property is 'Text' (type 'String')

有人可以帮忙吗?我在 xaml 中设置列​​的原因是我可以将宽度设置为星形大小并使列的宽度相等。

我看到大多数示例都使用 ObservableCollection,但如果我可以绑定到列表,为什么我必须使用它?

如果我的示例需要进一步说明,请告诉我

编辑:我现在拥有的:

XAML:

            <toolkit:DataGrid Name="dgFruit" 
            ItemsSource="{Binding}"
            AutoGenerateColumns="False">

                <toolkit:DataGrid.Columns>
                    <toolkit:DataGridTextColumn 
                        Header="Name"
                        Width="5*"/>

                    <toolkit:DataGridComboBoxColumn 
            Header="Color"
            Width="5*"/>

                    </toolkit:DataGrid.Columns>
</toolkit:DataGrid>

C#:

DataContext = fruitList;

实际上,当我使用 DataContext 时,我没有得到任何项目。当我使用 ItemSource 时,我得到空行,但行数正确,所以这似乎更符合正确的行。

如果我让它自动生成列,我可以让数据显示出来。如果我将 autogeneratecolumns 设置为 false,然后在 xaml 中指定我的列,就像我想使用星号大小一样,我会得到正确的列数,但没有文本!

【问题讨论】:

    标签: c# wpf visual-studio-2008 list datagrid


    【解决方案1】:

    首先,这个:

    dgFruit.ItemsSource = "{Binding}"
    

    应将项目源设置为包含大括号中的单词 Binding 的字符串。这几乎肯定不是你想要的(事实上,如果你这样做,你最终应该得到一个有九行的网格,一个对应字符串中的每个字符!)。您可以在 XAML 或后面的代码中设置 ItemsSource,但您不应该两者都做。请尝试以下操作:

    <toolkit:DataGrid Name="dgFruit"       
                      ItemsSource="{Binding}">
        ...
    </toolkit:DataGrid>
    

    然后在你的视觉构造函数中:

    ...
        InitializeComponents();
        this.DataContext = fruitList;
    ...
    

    现在整个视觉对象的数据上下文是 List,并且网格的 ItemsSource 设置为同一个对象。我在这里假设fruitList 是视觉本身的一个领域。

    列的绑定应该类似于:

            <toolkit:DataGridTextColumn Header="Name"
                                        Binding="{Binding Name}"
                                        Width="5*" />
            <toolkit:DataGridComboBoxColumn Header="Color"
                                            ItemsSource="{Binding Source={StaticResource AllColors}}"
                                            SelectedValueBinding="{Binding Path=Color}"
                                            TextBinding="{Binding Path=Color}"
                                            Width="5*" />
    

    其中 AllColors 被定义为资源(​​在这种情况下):

    <x:Array x:Key="AllColors"
             Type="sys:String">
        <sys:String>Orange</sys:String>
        <sys:String>Yellow</sys:String>
    </x:Array>
    

    这应该让你开始。

    【讨论】:

    • 它可以,但是当我这样做时,我在 xaml 中定义的列将被忽略,它会在左侧添加新的列。我可以以编程方式为这些自动生成的列设置星号吗?
    • 您可以关闭自动生成的。在 XAML 中的 DataGrid 上:AutoGenerateColumns="False"
    • 谢谢!我不知道前几天我怎么没有尝试过 - 尝试了上千种变化,但就是这样。想我可能需要阅读更多关于数据绑定的内容。
    【解决方案2】:

    WPF 不支持绑定到字段。创建一个访问fruitList 的属性并绑定到该属性。

        // this is the field. you can't bind to this
        private readonly List<Fruit> fruitList = new List<Fruit>();
    
        // this is the property. you can bind to this
        public List<Fruit> FruitList
        {
            get { return fruitList; }
        }
    

    使用dgFruit.DataContext = this; 而不是dgFruit.ItemsSource = "{Binding}";

    如果你想在 ComboBox 中显示这些,你需要将这些 DataGridComboBoxColumn 绑定到一个颜色列表,而不仅仅是一个字符串。例如,您的班级可能看起来像

    public class Fruit
    {
        public string Name { get; set; }
        public string Color { get; set; } // bind the combobox selectedvalue to this
    
        public List<string> AvailableColors { get; set; } // bind the combobox ItemsSource to this
    }
    

    如果您愿意,可以使用List。 ObservableCollection 的优势在于它已经为您实现了INotifyCollectionChanged 和INotifyPropertyChanged

    【讨论】:

    • 我不明白你创建一个访问fruitlist的属性是什么意思。我想我可以使用 ObservableCollection,就像我在其他地方使用列表一样。我不明白它需要是一个列表。我希望该列表是 Fruit.Color 或 Fruit.Name 中的所有值。 gridview shuold 显示原始关系,即 Apple -> Red 和 Banana -> Yellow 是值,但如果我双击 Apple,我会看到水果对象的所有选项的组合,因此 Apple 和 Banana,以及与 Color 类似的组合。 .
    猜你喜欢
    • 2011-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-10
    • 2011-08-15
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    相关资源
    最近更新 更多