WPF Datagrid selecteditem = null в MVVM

Я пытаюсь работать с сеткой данных, используя шаблон MVVM. Проблема в том, что всякий раз, когда я меняю свойство виртуальной машины, привязанное к SelectedItem, к null, View не отменяет выбор текущего выбранного элемента. Это моя привязка в 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 также отменит выбор строки. Вместо этого он остается выбранным, и если я попытаюсь щелкнуть ту же строку, свойство не обновится. Если я нажму на любую другую строку, свойство изменится, как ожидалось.

Есть ли способ отменить выбор сетки данных, если для ее свойства установлено значение null? Также я ищу решение MVVM, так как не хочу писать код. Я могу решить эту проблему, написав код, так что не тратьте время на предложения таких решений :)

l.e .: это моя собственность в ВМ:

public RPLUser SelectedUser
        {
            get
            {                
                return selectedUser;
            }
            set
            {
                selectedUser = value;
                OnPropertyChanged("SelectedUser");
            }
        }

Заранее спасибо!


person Florin Bombeanu    schedule 20.10.2011    source источник
comment
Когда вы устанавливаете свойство в своей модели просмотра, вызываете ли вы событие OnPropertyChanged, чтобы View знал, что ему нужно обновить?   -  person Purplegoldfish    schedule 20.10.2011
comment
Да, я редактирую описание, чтобы тоже упомянуть об этом. Хороший вопрос, спасибо!   -  person Florin Bombeanu    schedule 20.10.2011
comment
Можете ли вы опубликовать код, который вы используете для установки свойства в вашей виртуальной машине, а также код для самого свойства?   -  person Purplegoldfish    schedule 20.10.2011
comment
Установка UpdateSourceTrigger = PropertyChanged в вашей привязке может помочь.   -  person Louis Kottmann    schedule 20.10.2011
comment
Я бы попробовал OnPropertyChanged (); Может быть что-то странное происходит с привязкой, но выглядит нормально. Пробовали ли вы установить точку останова для набора, чтобы увидеть, будет ли SelectedUser снова установлен через некоторое время после того, как вы установили его в NULL? Также убедитесь, что вы устанавливаете свойство SelectedUser, а не возвращаемую переменную.   -  person Purplegoldfish    schedule 20.10.2011
comment
UpdateSourceTrigger не решил проблему. Я пробовал это со всеми возможными значениями, включая PropertyChanged. Также пробовал OnPropertyChanged (). Это тоже не решило. Убедился, что я устанавливаю для свойства значение null, а не частное поле, а также убедился, что оно остается нулевым и ни один другой компонент не устанавливает его обратно.   -  person Florin Bombeanu    schedule 20.10.2011
comment
Решил это. Оказалось, что я не устанавливал для свойства SelectedUser значение null, а для нового User (). Решил, сначала установив для него значение null, а затем создав для него новый объект. Ответ Purplegoldfish привел меня к решению, поэтому, пожалуйста, опубликуйте ответ, чтобы я мог отметить его как принятый. Спасибо.   -  person Florin Bombeanu    schedule 20.10.2011


Ответы (4)


Я рекомендую проверить Output Window в Visual Studio и посмотреть, не дает ли какой-нибудь Binding сбой.

Вы уверены, что когда вы что-то выбираете, выбор обновляется в свойстве SelectedUser?

Вы установили точку останова в установщике SelectedUser и видите, что она срабатывает, когда вы выбираете что-то в сетке данных?

Причин, по которым этот Binding сломался, могло быть много ...

  1. SelectedUser другого типа, чем индивидуальный Users.
  2. SelectedUser не совпадает по ссылке ни с одним элементом в Users.
  3. Как и где вы устанавливаете ноль?

Следующий код в моем случае отлично работает ...

    <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, набор данных отменяет выбор. Возможно, вам может потребоваться предоставить нам больше информации о том, как вы на самом деле устанавливаете значение как null.

person WPF-it    schedule 20.10.2011
comment
Вы правы, я не устанавливал для свойства значение null, как следовало бы. Я создавал новый объект вместо того, чтобы устанавливать для него значение null. Решил это, сначала установив для свойства значение null, а затем предоставив ему новый объект. Спасибо! - person Florin Bombeanu; 20.10.2011

Вы пробовали установить IsSynchronizedWithCurrentItem="True" в свойствах xaml для DataGrid? AFAIK, это позволит вам отменить выбор, установив для SelectedUser значение null.
Я не могу протестировать его в данный момент, но вы также можете попытаться добавить это в установщик своего свойства:

set
{
    selectedUser = value;
    OnPropertyChanged("SelectedUser");

    ICollectionView collectionView = CollectionViewSource.GetDefaultView(Users);
    collectionView.MoveCurrentTo(selectedUser);

}

(Чтобы ICollectionView что-либо делало, вам нужно установить IsSynchronizedWithCurrentItem)
Как я уже сказал, я не могу проверить это прямо сейчас. Кроме того, установщик свойства, вероятно, не лучшее место для его размещения. Возможно, локально создайте обработчик событий для PropertyChangedevent и поместите туда эту логику.

Дайте мне знать, если это поможет, иначе я посмотрю, смогу ли я провести небольшой тест ...

person RoelF    schedule 20.10.2011
comment
У меня была аналогичная проблема, и настройка IsSynchronizedWithCurrentItem="True" у меня сработала !! - person Satfactor; 20.06.2013

Да, возможно, потребуется добавить XAML UpdateSourceTrigger для обновления пользовательского интерфейса.

SelectedItem="{Binding SomeProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
person MtEdenCodeLab    schedule 20.10.2011

DataGrid не снимает выделение автоматически, поскольку для свойства DataGridRow IsSelected должно быть установлено значение 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 должно иметь свойство Isselected

Затем, прежде чем вы установите SelectedUser в ноль ... просто сделайте SelectedUser.IsSelected=False

И не забудьте прикрепить этот стиль к DataGridRowStyle в Datagrid

Я использую WPFToolkit, вы можете изменить стиль, если нацеливаетесь на .NET 4.0

person Ankesh    schedule 20.10.2011
comment
вы можете удалить BasedOn BasedOn="{StaticResource {x:Type WPFToolkit:DataGridRow}}" - person Ankesh; 20.10.2011
comment
Это не похоже на проблему того, что строка datagrid не отменяется. Я только что проверил это, и в базовой настройке datagrid отменяет выбор, когда для выбранного элемента установлено значение null через привязку. - person WPF-it; 20.10.2011
comment
@AngelWPF Я попытался сделать это так, но это не сработало, поэтому я попробовал это стиль - person Ankesh; 20.10.2011