代码之家  ›  专栏  ›  技术社区  ›  knutter539

WPF DataGrid ComboBoxColumn未更新绑定数据

  •  0
  • knutter539  · 技术社区  · 6 年前

    我的datagrid中有一个下拉列,组合框的选项存储在 TMFCNComponentStatus_threed 桌子我的主表有一个名为[状态]的列,它对应于该表中的键列。

    我的datagrid中的每一行的组合框中都会显示正确的状态[描述],但当用户更改选择时,数据库不会更新,即使一切看起来都正常工作。我已将“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()
    

    谢谢你抽出时间。

    数据库:

    enter image description here

    状态表的内容: enter image description here

    数据网格: enter image description here

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

    1 回复  |  直到 6 年前
        1
  •  1
  •   Community CDub    4 年前

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

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

    Mode=TwoWay 没有必要对其进行绑定。这是上绑定的默认模式 ComboBox.SelectedValue .

    您可以从上的装订中删除所有这些装饰 TextBlock.Text :考虑到它,它根本无法更新源代码,因此没有必要为XAML添加详细的说明,说明它应该如何以及何时执行它无论如何都无法执行的操作。


    完整的工作示例

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

    我不知道你的专栏是否不是你想象的那样,或者是什么。

    主窗口。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;
        }
    

    主窗口。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>