一番手っ取り早いのは、Item に選択状態プロパティを追加して DataGridRow の IsSelected にバインドさせることですかねー。
View側を簡単に書いてみます。
<Window.DataContext>
<vm:MainWindowViewModel />
</Window.DataContext>
<Grid>
<DataGrid ItemsSource="{Binding Path=List}" AutoGenerateColumns="False" >
<DataGrid.Columns>
<DataGridTextColumn Header="No" Binding="{Binding Path=No}" />
<DataGridTextColumn Header="Date" Binding="{Binding Path=Date, StringFormat=yyyy/MM/dd}" />
</DataGrid.Columns>
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected}" />
</Style>
</DataGrid.RowStyle>
</DataGrid>
</Grid>
ViewModel 側はこんな感じ。
public class ItemViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
public int No { get; set; }
public DateTime Date { get { return DateTime.Now.AddDays(No); } }
private bool isSelected;
public bool IsSelected
{
get { return isSelected; }
set { isSelected = value; OnPropertyChanged("IsSelected"); }
}
}
public class MainWindowViewModel
{
public List<ItemViewModel> List { get; set; }
/// <summary>
/// コンストラクタ
/// </summary>
public MainWindowViewModel()
{
List = new List<ItemViewModel>();
for (int i = 0; i < 100; i++)
List.Add(new ItemViewModel() { No = i });
}
}
この方法を参考に実装してみたのですが
返信削除ある1行を選択→
他のコントロールを選択してデータグリッドを非アクティブに→
データグリッド上にカーソルを移し非アクティブのままマウスホイールでスクロール→
最初に選択した行がスクロールされて見えなくなってから他の行を選択
とすると、最小に選択した行のIsSelectedがfalseになってくれないです。
IsSelectedのBindingは見えない行には適用されないのでしょうか??
.NET 4.5です。
CanContentScrollをfalseにすると問題が起きなくなるので、UIの仮想化?が影響しているかもしれません。
UIが仮想化されているのが原因でしょう。こういうことかと
返信削除http://qiita.com/wonderful_panda/items/36bf500094cc42f7ea97