Изменения, не видимые в пользовательском интерфейсе после обновления данных в DataGrid

#c# #wpf #datagrid

Вопрос:

Когда я изменяю значения с помощью DataContext to set data for CheckBox , почему он возвращает исходное значение при прокрутке вниз или прокрутке вверх? Есть ли какой-либо способ восстановления?

Когда я прокручиваю вниз или вверх, я ожидаю, что он не вернет флажки к их исходным значениям.


Код XAML

 <DataGrid x:Name="list_account_instagram"
          Background="#DDDDDD"
          CanUserResizeColumns="False"
          CanUserSortColumns="False"
          CanUserAddRows="False">
    <DataGrid.Columns>
        <materialDesign:DataGridTextColumn Width="0.4*"
                                           Binding="{Binding STT}"
                                           Header="#" />
        <DataGridCheckBoxColumn Width="0.35*" Binding="{Binding CHECK, Mode=OneTime}">
            <DataGridCheckBoxColumn.Header>
                <Border Background="Transparent">
                    <CheckBox Name="checkallins" Click="Checkallins_Click"/>
                </Border>
            </DataGridCheckBoxColumn.Header>
        </DataGridCheckBoxColumn>

        <materialDesign:DataGridTextColumn Binding="{Binding UID}" Width="*"
                                           Header="UID" />
        <materialDesign:DataGridTextColumn Binding="{Binding PASSWORD}" Width="*"
                                           Header="Password"/>
        <materialDesign:DataGridTextColumn Binding="{Binding COOKIE}" Width="*"
                                           Header="Cookie"/>
        <materialDesign:DataGridTextColumn Binding="{Binding TEN}" Width="*"
                                           Header="Tên"/>
        <materialDesign:DataGridTextColumn Binding="{Binding AVATAR}" Width="*"
                                           Header="Avatar"/>
        <materialDesign:DataGridTextColumn Binding="{Binding TT}" Width="*"
                                           Header="Tình Trạng"/>
        <materialDesign:DataGridTextColumn Binding="{Binding MESSAGE}" Width="*"
                                           Header="Trạng Thái"/>
    </DataGrid.Columns>
</DataGrid>
 

C#

 private void Checkallins_Click(object sender, RoutedEventArgs e)
{
    if (checkallins.IsChecked.Value)
    {
        if (list_account_instagram.Items.Count > 0)
        {
            for (int i = 0; i < list_account_instagram.Items.Count; i  )
            {
              GetCell(list_account_instagram, i, 1).DataContext = new { CHECK = true };
            }
        }
    }
    else
    {
        if (list_account_instagram.Items.Count > 0)
        {
            for (int i = 0; i < list_account_instagram.Items.Count; i  )
            {
              GetCell(list_account_instagram, i, 1).DataContext = null;
              GetCell(list_account_instagram, i, 1).DataContext = new { CHECK = false };
            }
        }
    }
}
 

Чтобы лучше описать проблемное поведение, есть видео: https://files.fm/u/2xxgqrqra#/view/p4jw246e3

Комментарии:

1. Вы все равно выполняете прокрутку вверх / вниз? Вносите ли вы какие-либо изменения в данные?

2. @Tatranskymedved у меня нет функции для обработки прокрутки вверх и прокрутки вниз

Ответ №1:

Проблема связана с использованием OneTime привязки. Это приведет к тому, что данные будут загружаться только во время инициализации, но после любых изменений (либо в пользовательском интерфейсе, либо в коде) это не повлияет на саму коллекцию.

Это вызывает проблему, когда вы видите разные вещи в «пользовательском интерфейсе» и разные вещи в «code-behind». Если бы вы отлаживали фактические значения (при нажатии заголовка DataGrid ), вы были бы удивлены, откуда берутся эти значения.

Исправить довольно просто, необходимо обновить Binding режим. Вместо этого:

 Binding="{Binding CHECK, Mode=OneTime}">
 

Вы должны использовать:

 Binding="{Binding CHECK}">
<!-- or this -->
Binding="{Binding CHECK, Mode=TwoWay}">
 

РЕДАКТИРОВАТЬ: из комментариев OP похоже, что проблема также заключается в установке bool значения для элементов в DataGrid . Вы не должны назначать там новые объекты, вместо этого вы должны работать с DataContext DataGrid . Вы можете добиться этого с помощью:

 var isChecked = checkallins.IsChecked.Value;

foreach(var item in list_account_instagram.Items)
{
    // Put instead of `MyClass` actual class you are using (prob. `InstagramAccount`)
    var myItem = item as MyClass;

    if(item != null)
    {
        myItem.CHECK = isChecked;
    }
}
 

Комментарии:

1. При вызове GetCell(list_account_instagram, i, 1).DataContext = new { CHECK = true }; я получаю сообщение об ошибке, как показано ниже, есть ли способ это исправить? System.InvalidOperationException: 'A TwoWay or OneWayToSource binding cannot work on the read-only property 'CHECK' of type '<>f__AnonymousType1 1[Система. Логическое значение]’.»