【问题标题】:WPF DataGrid ComboBoxColumn Not Updating Bound DataWPF DataGrid ComboBoxColumn 未更新绑定数据
【发布时间】:2018-10-26 13:39:24
【问题描述】:

我的数据网格中有一个下拉列,组合框的选项存储在 tmfCNCComponentStatus_threed 表中。我的主表有一个名为 [Status] 的列,它对应于该表中的键列。

正确的状态 [描述] 显示在我的数据网格中每一行的组合框中,但是当用户更改选择时,数据库没有更新,即使一切看起来都正常工作。正如许多类似帖子中所见,我将“UpdateSourceTrigger”设置为 PropertyChanged,但仍然没有骰子。任何见解将不胜感激!

<CollectionViewSource x:Key="StatusItems"/>

                               <DataGridTemplateColumn x:Name="StatusColumn" Header="Status" Width="*" IsReadOnly="False">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock x:Name="cboStatus" Text="{Binding Path=Description}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox x:Name="StatusCombo" SelectedValuePath="CNCComponentStatusKey" DisplayMemberPath="Description" SelectedValue="{Binding Status, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding Source={StaticResource StatusItems}}" IsEditable="True" IsSynchronizedWithCurrentItem="True"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>

背后的代码:

Dim com As String = "SELECT tmfCNCComponent_threed.[CNCComponentKey]
    ,tmfCNCComponent_threed.[CompanyID]
    ,tmfCNCComponent_threed.[JobNumber]
    ,tmfCNCComponent_threed.[LogNumber]
    ,tmfCNCComponent_threed.[Customer]
    ,tmfCNCComponent_threed.[DueDate]
    ,tmfCNCComponent_threed.[JobLeader]
    ,tmfCNCComponent_threed.[CADProgrammer]
    ,tmfCNCComponent_threed.[Salesperson]
    ,tmfCNCComponent_threed.[CNCProgrammer]
    ,tmfCNCComponent_threed.[ComponentDescription]
    ,tmfCNCComponent_threed.[ComponentFilePath]
    ,tmfCNCComponent_threed.[Material]
    ,tmfCNCComponent_threed.[ComponentSizeX]
    ,tmfCNCComponent_threed.[ComponentSizeY]
    ,tmfCNCComponent_threed.[ComponentSizeZ]
    ,tmfCNCComponent_threed.[QuantityShown]
    ,tmfCNCComponent_threed.[QuantityMirror]
    ,tmfCNCComponent_threed.[UpdateTime]
    ,tmfCNCComponent_threed.[Status]
    ,tmfCNCComponent_threed.[ProgStarted]
    ,tmfCNCComponentStatus_threed.[Description]
    FROM [test_3DimensionalDB].[dbo].[tmfCNCComponent_threed]
    INNER JOIN tmfCNCComponentStatus_threed
    ON tmfCNCComponent_threed.Status = tmfCNCComponentStatus_threed.CNCComponentStatusKey 
    WHERE [ComponentDescription] " & component & " 'trode%' AND [CompanyID]='" & company & "' AND [Status]" & status & "ORDER BY [UpdateTime] DESC"

    Dim Adpt As New SqlDataAdapter(com, con)
    con.Open()
    Dim ds As New DataSet()
    Adpt.Fill(ds, "dbo.tmfCNCComponent_threed")
    dataGrid1.ItemsSource = ds.Tables("dbo.tmfCNCComponent_threed").DefaultView

    con.Close()

    con.Open()
    Dim statusCVS As CollectionViewSource = FindResource("StatusItems")

    Dim com2 As String = "SELECT * FROM tmfCNCComponentStatus_threed"
    Dim AdptStatus As New SqlDataAdapter(com2, con)
    AdptStatus.Fill(ds, "dbo.tmfCNCComponentStatus_threed")

    Dim statusRows = ds.Tables("dbo.tmfCNCComponentStatus_threed").Rows
    Dim statuses As New List(Of Object)

    For Each row As DataRow In statusRows
        statuses.Add(New With {
        .Status = CInt(row("CNCComponentStatusKey")),
        .Description = CStr(row("Description"))
    })
    Next

    statusCVS.Source = statuses
    con.Close()


    RowCount()
    searchBox.Clear()

感谢您的宝贵时间。

数据库:

状态表的内容:

数据网格:

这是昨天为让我明白这一点而提出的这个问题的第一部分: Part 1

【问题讨论】:

  • DataGridComboBoxColumn 很难使用。坚持使用模板栏。您是否尝试过 PresentationTraceSources.TraceLevel=High 和 DebugView?
  • 我无法让您在另一篇文章中链接的调试器在我的 Windows 10 机器上正常工作。它根本不会显示任何调试信息:(
  • 您尝试调试了吗?附加到进程?
  • 顺便说一句,您正在对StatusItems 中的内容保密。除非你说出里面有什么,否则没有人可以帮助你。是收藏吗?收藏中有什么?对象还是数据行?属性或列的名称和类型是什么?
  • 我不明白我在隐藏什么?在上面的 xaml 中,您可以看到我声明了我的 collectionviewsource。在代码中,特别是你昨天帮助我创建的底部部分,你可以看到我在哪里用数据填充视图源

标签: wpf vb.net data-binding wpfdatagrid


【解决方案1】:

根据不同问题中 cmets 中的信息,您可能需要将 SelectedValuePath="Status" 更改为 SelectedValuePath="CNCComponentStatusKey"。组合框中项目的列名称或属性对于回答此问题至关重要,而您尚未提供它们。

当单元格离开编辑模式时,网格将更新 DataRowView 列值。

Mode=TwoWay 绑定是不必要的。这是ComboBox.SelectedValue 上绑定的默认模式。

您可以从TextBlock.Text 上的绑定中删除所有这些装饰:当您考虑它时,它根本无法更新源代码,因此无需详细说明如何以及何时使用它来弄乱您的 XAML应该做一些无论如何都做不到的事情。


完整的工作示例

这是我测试上述答案的代码。它更新主表中的行。它不会将表保存到数据库中。那是另外一回事。

我不知道您的专栏是否没有按照您的想法命名,或者是什么。

MainWindow.xaml.cs

    public MainWindow()
    {
        InitializeComponent();

        LoadData();
    }

    #region Lists
    private static List<String> _status = new List<String>
    {
        "Ready",
        "Not Ready",
        "Weary",
        "Disordered",
    };

    private static List<String> _words = new List<String>
    {
        "Ewwrigowasaus",
        "Skubreuph",
        "Creecroicr",
        "Eunthaudrawtr",
        "Ootwoww",
        "Meuleetroithr",
        "Rewshr",
        "Scoysl",
        "Scewziexul",
        "Kawxayzeec",
    };
    #endregion Lists

    protected void LoadData()
    {
        DataTable dtMain = new DataTable();

        dtMain.Columns.Add("Status", typeof(int));
        dtMain.Columns.Add("Programmer", typeof(String));

        _words.ForEach(w =>
        {
            var row = dtMain.NewRow();
            row[0] = ((int)w[0] % 2) + 1;
            row[1] = w;
            dtMain.Rows.Add(row);
        });

        DataTable dtStatus = new DataTable();

        dtStatus.Columns.Add("CNCComponentStatusKey", typeof(int));
        dtStatus.Columns.Add("Description", typeof(String));

        _status.ForEach(s =>
        {
            var row = dtStatus.NewRow();
            row[0] = dtStatus.Rows.Count + 1;
            row[1] = s;
            dtStatus.Rows.Add(row);
        });

        DataGrid.ItemsSource = dtMain.DefaultView;

        var cvs = (FindResource("StatusItems") as CollectionViewSource);
        
        cvs.Source = dtStatus.DefaultView;
    }

MainWindow.xaml

<Window.Resources>
    <CollectionViewSource x:Key="StatusItems" />
</Window.Resources>
<Grid>
    <DataGrid x:Name="DataGrid" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Programmer}" Header="Programmer" />
            <DataGridTemplateColumn Header="Status">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Status}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <ComboBox
                                ItemsSource="{Binding Source={StaticResource StatusItems}}"
                                SelectedValue="{Binding Status, UpdateSourceTrigger=PropertyChanged}"
                                DisplayMemberPath="Description"
                                SelectedValuePath="CNCComponentStatusKey"
                                x:Name="Combo"
                                />
                            <!-- Selected value in combo -->
                            <Label Content="{Binding SelectedValue, ElementName=Combo}" />
                            <!-- Value of Status column in row -->
                            <Label Content="{Binding Status}" />
                        </StackPanel>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

【讨论】:

  • 我已经进行了所有这些更改,现在当我更改组合框值之一时,数据网格中的所有值都在更改以匹配大声笑。他们仍然没有改变数据库
  • 不要把组合放在CellTemplate,我删除了那个建议,因为我看到了同样荒谬的行为。在CellEditingTemplate 它工作正常,除了你必须离开编辑模式才能让它更新,这是一个拖动 IMO。
  • 由于 [Status] 是主表中的列,用作包含组合框选项的另一个表的 FK,我想我确实希望 [Status] 作为 SelectedValuePath。我希望绑定查看行的 [Status] 值并查找该状态的相应描述
  • 你错了。您误解了 SelectedValuePath 的含义。它包含 ComboBox 中对象(或行)的属性(或列)的名称。不是主电网。组合框。 SelectedValue 绑定绑定到主网格行的属性。
  • 您希望它如何查找 ComboBox 中的描述?基于什么?想想吧。
猜你喜欢
  • 2012-08-17
  • 2014-08-23
  • 2011-07-21
  • 2011-08-12
  • 2021-03-18
  • 2018-12-28
  • 2013-06-01
  • 2023-03-07
  • 1970-01-01
相关资源
最近更新 更多