单击“内容”时,在“模板列”中选择“数据网格单元格”

本文关键字:选择 数据 网格 单元格 模板列 数据网 内容 单击 | 更新日期: 2023-09-27 18:07:28

所以,我正在构建一个基于MySQL的程序。我有很多数据列,从整数到双精度到日期到字符串,我刚刚决定用模板列创建整个表,以便在UI和编程角度上保持一点一致性。该系统的关键点在于,当用户退出单元格时,它需要自动向数据库发送新的信息。为了适应这一点(在过去我有其他被动问题),我只是定位已选择的列和行,将坐标传递给底层数据表,并使用它来创建更新字符串并将它们更新到数据库(这有点简化)。

这使我陷入了我的新问题。以前我使用的是文本列,现在我使用的是带有文本框(或遮罩文本框)的模板列。当单元格被点击时,文本列会自然而然地处理单元格的选择,以便获得选择坐标,而模板列不会在可视化树中工作,除非单元格被选项卡或以其他方式导航到,否则不会选择容器单元格,但当点击进入时则不会。当单击文本框时,我试图通过手动工作可视化树来手动选择单元格,但无济于事。奇怪的是,这个过程一直有效,直到我点击一个必须滚动才能到达的列(这是相同的)。有人对如何解决这个问题有什么建议吗?以下是我的XAML和Code-Behind示例。 XAML:

<DataGrid x:Name="datagrid_1" PreviewMouseLeftButtonDown="UIElement_OnMouseLeftButtonDown1">
    <DataGrid.Columns>
        <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
        <xctk:MaskedTextBox LostFocus="textbox1_LostFocus" BorderBrush="Transparent" AutoSelectBehavior="OnFocus" Text="{Binding Path = penetration, Mode = TwoWay, ValidatesOnExceptions = true, NotifyOnValidationError = false, UpdateSourceTrigger = PropertyChanged}" Mask="000 %"  PromptChar=" " HidePromptOnLeave="True"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    </DataGrid.Columns>
</DataGrid>

后台代码:

private void UIElement_OnLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    if (sender.GetType().ToString() == "TextBox")
    {
        var dep = (DependencyObject)e.OriginalSource;
        dep = VisualTreeHelper.GetParent(dep);
        if (dep == null)
        {
            return;
        }
        if (dep is DataGridCell)
        {
            datagrid_1.SelectedItems[0] = dep;
        }
    }
}
private void textbox1_LostFocus(object sender, RoutedEventArgs e)
{
    try
    {
        int rowindex = datagrid_1.Items.IndexOf(datagrid_1.SelectedCells[0].Item);                
        int columnindex = datagrid_1.SelectedCells[0].Column.DisplayIndex;
        string groupnumber = datatable1.Rows[rowindex][1].ToString();
        string columnname = datatable1.Columns[columnindex].ColumnName.ToString();
        string newinfo = datatable1.Rows[rowindex][columnindex].ToString();
        instantupdatecall(groupnumber, columnname, newinfo);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

我试图简化一切,使它更容易适应,但我留下了重要的部分。如果有人有什么建议,我将不胜感激。

单击“内容”时,在“模板列”中选择“数据网格单元格”

你可能想使用数据绑定。

基本上,有一个"模型"类来保存实际的数据,这些数据显示并链接到屏幕上的单元格。在setter中,你可以写入你的DB。

的例子:XAML:

<DataGrid ItemsSource="{Binding Source=list}">
    <DataGrid.Columns>                
        <DataGridTextColumn Header="ID" Binding="{Binding ID}"/>
        <DataGridTextColumn Header="Date" Binding="{Binding Date}"/>
   </DataGrid.Columns>
</DataGrid>
c#:

public class SomeObject
{
    string id;
    DateTime date;
    public string ID
    {
        get { return id; }
        set {
            id = value;
            UpdateDB();
        }
    }
    public DateTime Date
    {
        get { return date; }
        set {
            date = value;
            UpdateDB();
        }
    }
    private void UpdateDB() {
        // Make some SQL, and work with your DB.
        // You maybe want to send arguments to this method about what has to be updated.
    }
}

如果你知道如何使用WPF和它的数据绑定,你就很少需要触发器和你在例子中尝试的hack了。第一次为DataGrid正确绑定是相当棘手的,但一旦设置好,它会使您的生活变得容易得多。

您可以在DataGridColumns中使用<DataTemplate>,它们不必像我展示的那样是DataGridTextColumn,但这是一个不同的问题。:)