Получение отредактированного значения DataGridTemplateColumn в DataGrid, привязанного к результатам запроса LINQ - PullRequest
0 голосов
/ 08 марта 2019

У меня есть приложение WPF с сеткой данных, которую я привязываю к пользовательскому запросу LINQ to SQL в моей модели представления, которая объединяет столбцы из двух разных таблиц:

public ICollectionView SetsView { get; set; }

public void UpdateSetsView()
{
    var sets = (from s in dbContext.Sets
                join o in dbContext.SetParts on s.ID equals o.SetID into g1
                select new
                {
                    s.ID,
                    s.SetNumber,
                    s.SetTitle,
                    s.SetType,
                    s.SetNotes,
                    s.SetUrl,
                    s.HaveAllParts,
                    s.NumberOfSets,
                    s.IsBuilt,
                    s.DateAdded,
                    s.LastModified,
                    UniqueParts = g1.Count(),
                    TotalParts = g1.Sum(o => o.Quantity)
                }
                );
    SetsView = CollectionViewSource.GetDefaultView(sets);
}

Коллекция SetsView привязана к моемуСетка данных и так как мне нужно иметь возможность редактировать значение SetNotes для любой строки и сохранять его обратно в таблицу Sets в моей базе данных, я добавил обработчик событий для CellEditEnding (CellEditEnding = "dgST_Sets_CellEditEnding") в определение DataGrid и создал этот столбец:

<DataGridTemplateColumn Header="Set Notes" 
                        SortMemberPath="SetNotes" 
                        Width="*">
    <DataGridTemplateColumn.HeaderStyle>
        <Style TargetType="{x:Type DataGridColumnHeader}">
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
        </Style>
    </DataGridTemplateColumn.HeaderStyle>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding SetNotes, Mode=OneWay}" Margin="5,0,5,0"
                        HorizontalAlignment="Stretch" VerticalAlignment="Center" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <TextBox Text="{Binding SetNotes, Mode=OneWay}" Margin="5,0,5,0"
                        HorizontalAlignment="Stretch" VerticalAlignment="Center" 
                        />
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

Проблема в том, что, когда я запускаю приложение и редактирую столбец «Задать заметки» в любой строке, я не могу понять, как получить новое значение отредактированной ячейки из аргументов события.Я подумал, что могу привести аргументы EditingElement к аргументам события в TextBox (см. Обработчик ниже), но когда я запускаю приложение, редактирую строку и изменяю значение SetNotes, тип EditingElement - это ContentPresenter, а не TextBox, и я могу это сделать.не узнать, как получить измененное значение.

private void dgST_Sets_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
    string newValue = ((TextBox)e.EditingElement).Text;

    //Code here to update table
}

Пожалуйста, помните, что я привязываюсь к пользовательскому запросу LINQ to SQL, так что это не проблема классической привязки модели.Также обратите внимание, что при привязке значения SetNotes в столбце моего шаблона у меня нет другого выбора, кроме использования Mode = OneWay, поскольку использование любого другого параметра дает мне ошибки времени выполнения при доступе к свойству только для чтения - может ли это быть проблемой?

Я потратил часы на это и без конца погуглил без радости - кто-нибудь может мне помочь, пожалуйста?

1 Ответ

1 голос
/ 08 марта 2019

Это должно работать:

private void dgST_Sets_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
    ContentPresenter cp = e.EditingElement as ContentPresenter;
    if (cp != null && VisualTreeHelper.GetChildrenCount(cp) > 0)
    {
        TextBox textBox = VisualTreeHelper.GetChild(cp, 0) as TextBox;
        if (textBox != null)
        {
            string newValue = textBox.Text;
        }
    }
}
...