WPF Datagrid selecteditem = null в MVVM

#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 разрыва может быть много …

  1. SelectedUser имеет другой тип, чем индивидуальный Users .
  2. SelectedUser не совпадает по ссылке ни с какими элементами в Users .
  3. Как и где вы устанавливаете значение 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 я пытался сделать это таким образом, но это не сработало, поэтому я попробовал использовать стиль