#wpf #binding #mvvm #datagrid #selecteditem
#wpf #привязка #mvvm #datagrid #выбранный элемент
Вопрос:
Я пытаюсь работать с сеткой данных, используя шаблон MVVM. Проблема в том, что всякий раз, когда я изменяю свойство виртуальной машины, которое привязано к SelectedItem, на null, представление не «отменяет выбор» текущего выбранного элемента. Это моя привязка в xaml:
<DataGrid Grid.Column="0" Grid.Row="0"
ItemsSource="{Binding Path=Users}"
AutoGenerateColumns="False"
CanUserAddRows="False"
IsReadOnly="True"
SelectedItem="{Binding Path=SelectedUser, Mode=TwoWay}">
Привязка SelectedItem выполняется из представления к виртуальной машине, поэтому в свойстве selectedUser у меня всегда есть выбранный объект. Проблема в том, что в виртуальной машине я делаю некоторые вещи, которые иногда меняют свойство selectedUser на null, поэтому я ожидаю, что datagrid также отменит выбор строки. Вместо этого он остается выбранным, и если я попытаюсь щелкнуть по той же строке, свойство не обновляется. Если я нажму на любую другую строку, свойство изменится, как и ожидалось.
Есть ли способ отменить выбор datagrid, если для его привязанного свойства установлено значение null? Также я ищу решение MVVM, поскольку я не хочу писать код позади. Я могу решить это, написав код, поэтому не тратьте время, предлагая такие решения 🙂
например: это моя собственность в виртуальной машине:
public RPLUser SelectedUser
{
get
{
return selectedUser;
}
set
{
selectedUser = value;
OnPropertyChanged("SelectedUser");
}
}
Заранее спасибо!
Комментарии:
1. Когда вы устанавливаете свойство в своей viewmodel, вызываете ли вы событие OnPropertyChanged, чтобы сообщить представлению, что оно нуждается в обновлении?
2. Да, я редактирую описание, чтобы также упомянуть об этом. Хороший вопрос, спасибо!
3. Можете ли вы опубликовать код, который вы используете для установки свойства в вашей виртуальной машине, а также код для самого свойства?
4. Установка UpdateSourceTrigger=PropertyChanged в вашей привязке может помочь.
5. Я бы попробовал OnPropertyChanged(«»); Может быть, с привязкой происходит что-то странное, но это выглядит нормально. Вы пробовали указывать точку останова в наборе, чтобы увидеть, будет ли selectedUser установлен снова через некоторое время после того, как вы установили для него значение NULL? Также убедитесь, что вы устанавливаете свойство selectedUser, а не переменную, которую оно возвращает.
Ответ №1:
Я рекомендую проверить Output Window
в Visual Studio и посмотреть, не происходит ли какой-либо Binding
сбой.
Вы уверены, что при выборе чего-либо выбор обновляется в SelectedUser
свойство?
Вы установили точку останова в setter of SelectedUser
и увидели, что она срабатывает при выборе чего-либо в datagrid?
Причин для этого Binding
разрыва может быть много …
SelectedUser
имеет другой тип, чем индивидуальныйUsers
.SelectedUser
не совпадает по ссылке ни с какими элементами вUsers
.- Как и где вы устанавливаете значение null?
Следующий код в моем случае работает отлично…
<tk:DataGrid MaxHeight="200" AutoGenerateColumns="False"
ItemsSource="{Binding}"
SelectedItem="{Binding MySelItem,
ElementName=MyDGSampleWindow,
Mode=TwoWay}"
IsReadOnly="True">
<tk:DataGrid.Columns>
<tk:DataGridTextColumn Header="Key"
Binding="{Binding Key,
Mode=OneWay}"/>
<tk:DataGridTextColumn Header="Value"
Binding="{Binding Value,
Mode=OneWay}"/>
</tk:DataGrid.Columns>
</tk:DataGrid>
Когда я устанавливаю MyDGSampleWindow.MySelItem
значение null, datagrid автоматически отменяет выбор. Возможно, вам может потребоваться предоставить нам больше информации о том, как вы на самом деле устанавливаете значение как null.
Комментарии:
1. Вы правы, я не устанавливал для свойства значение null, как следовало бы. Я создавал новый объект вместо того, чтобы устанавливать для него значение null. Решил проблему, сначала установив для свойства значение null, а затем присвоив ему новый объект. Спасибо!
Ответ №2:
Вы пытались установить IsSynchronizedWithCurrentItem="True"
в свойствах xaml для DataGrid? AFAIK, это позволит вам отменить его выбор, установив для selectedUser значение null.
Я не могу проверить это на данный момент, но вы также можете попробовать добавить это в параметр вашего свойства:
set
{
selectedUser = value;
OnPropertyChanged("SelectedUser");
ICollectionView collectionView = CollectionViewSource.GetDefaultView(Users);
collectionView.MoveCurrentTo(selectedUser);
}
( ICollectionView
Чтобы что-то сделать, вам нужно будет IsSynchronizedWithCurrentItem
установить)
Как я уже сказал, я не могу проверить это прямо сейчас. Кроме того, установщик свойства, вероятно, не лучшее место для его размещения. Возможно, создайте обработчик события для PropertyChanged
события локально и поместите туда эту логику.
Дайте мне знать, если это поможет, иначе я посмотрю, смогу ли я выполнить короткий тест…
Комментарии:
1. У меня была похожая проблема, и настройка
IsSynchronizedWithCurrentItem="True"
сработала для меня!!
Ответ №3:
Да, возможно, потребуется добавить XAML UpdateSourceTrigger для обновления пользовательского интерфейса.
SelectedItem="{Binding SomeProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Ответ №4:
DataGrid не отменит его автоматически, поскольку DataGridRow
IsSelected
для свойства s должно быть установлено значение False
.
Вы можете сделать это, установив стиль для DataGrid.. Нравится
<Style x:Key="dataGridRowStyle"
BasedOn="{StaticResource {x:Type WPFToolkit:DataGridRow}}"
TargetType="{x:Type WPFToolkit:DataGridRow}">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected}" />
</Style>
IsSelected
Свойство должно быть объектом, т.е. в вашем случае RPLUser
должно быть выбрано свойство
Затем, прежде чем вы установите значение SelectedUser
null… просто сделайте SelectedUser.IsSelected=False
И не забудьте прикрепить этот стиль к DataGridRowStyle
in Datagrid
Я использую WPFToolkit, вы можете изменить стиль, если вы нацелены .NET 4.0
Комментарии:
1. вы можете удалить BasedOn
BasedOn="{StaticResource {x:Type WPFToolkit:DataGridRow}}"
2. Похоже, что это не проблема с тем, что строка datagrid не отменяется. Я только что проверил это, и в базовой настройке datagrid отменяет выбор, когда выбранному элементу присваивается значение null через привязку.
3. @AngelWPF я пытался сделать это таким образом, но это не сработало, поэтому я попробовал использовать стиль