#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[Система. Логическое значение]’.»