Выберите ячейку DataGrid в столбце шаблона при нажатии на содержимое

Итак, я строю программу на основе MySQL. У меня есть много столбцов данных, начиная от целых чисел до двойных чисел и заканчивая датами и строками, и я только что решил создать всю таблицу из столбцов шаблонов, чтобы обеспечить их согласованность как с точки зрения пользовательского интерфейса, так и с точки зрения программирования. Ключевым моментом этой системы является то, что она должна автоматически отправлять новую информацию в базу данных, когда пользователь выходит из ячейки. Чтобы учесть это в прошлом (где у меня были другие пассивные проблемы), я просто поместил выбранный столбец и строку, передал координату в базовую таблицу данных и использовал ее для создания строк обновления и обновления их в базе данных (это немного упрощение).

Это подводит меня к моей новой проблеме. Ранее я использовал текстовый столбец, где теперь я использую шаблонный столбец с текстовым полем (или замаскированным текстовым полем). Текстовый столбец будет позаботиться о выделении ячеек при щелчке по ячейке, чтобы получить координаты выбора, в то время как столбец шаблона не так хорошо работает с деревом визуалов и не выбирает ячейку контейнера, если только ячейка не выбрана. на вкладке или иным образом перемещены к, но не при нажатии на. Я пытался вручную выбрать ячейку, вручную обрабатывая визуальное дерево при нажатии на текстовое поле, но безрезультатно. Странная часть заключается в том, что процесс работает, пока я не нажму на столбец (который идентичен), который мне пришлось прокрутить, чтобы добраться до. У кого-нибудь есть предложения относительно того, как подойти к этой проблеме? Вот образец моего 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>

Code-Behind:

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);
    }
}

Я попытался упростить все, чтобы сделать его немного легче, но я оставил важные части. Если у кого-то есть какие-либо предложения относительно того, как сделать эту работу, я был бы очень признателен.

1 ответ

Вы можете использовать привязку данных.

В основном, есть класс "Модель", который содержит фактические данные, которые представлены и связаны с ячейками на экране. Внутри сеттера вы можете написать в свою БД.

Пример:

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 и его привязку данных, вам редко нужны триггеры и хаки, которые вы пробовали в своем примере.
Довольно сложно впервые получить правильную привязку для DataGrid, но после настройки она сделает вашу жизнь намного проще.

Вы можете использовать <DataTemplate> внутри DataGridColumns они не должны быть DataGridTextColumn как я показал, но это другая проблема.:)

Другие вопросы по тегам