扩展了选择模式的选定项WPF DataGrid
我有一个使用mvvm的应用程序,它有一个将SelectionMode设置为Extended的DataGrid。我有两个按钮“上移”和“下移”,当点击时,应该将所选项目的位置上移或下移一点(仅当仅选择一个项目时) 这可以正常工作(要遵循的代码),但是,在执行移动后,它似乎会中断所选项目触发器。例如,如果我单击一个项目,将其向下移动4个点,单击另一个项目并尝试将其向上移动一个点,则先前移动的项目将再次被选中并移动。在VM中的“SelectItem”上设置的断点停止被命中,即使在清除所有选择并选择一个全新的行之后也是如此。如果选择模式设置为“单一”,则不会发生此问题 我已经尝试过启用和禁用虚拟化、与CurrentItem同步、不同的列表类型等,但没有任何改变这种行为。我在拔头发。有人能提出一个解决这个问题的办法吗 我的网格和按钮扩展了选择模式的选定项WPF DataGrid,wpf,mvvm,Wpf,Mvvm,我有一个使用mvvm的应用程序,它有一个将SelectionMode设置为Extended的DataGrid。我有两个按钮“上移”和“下移”,当点击时,应该将所选项目的位置上移或下移一点(仅当仅选择一个项目时) 这可以正常工作(要遵循的代码),但是,在执行移动后,它似乎会中断所选项目触发器。例如,如果我单击一个项目,将其向下移动4个点,单击另一个项目并尝试将其向上移动一个点,则先前移动的项目将再次被选中并移动。在VM中的“SelectItem”上设置的断点停止被命中,即使在清除所有选择并选择一个
<StackPanel Orientation="Horizontal">
<Button Margin="3" Content="Move Up">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:CallMethodAction TargetObject="{Binding}"
MethodName="MoveUp" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<Button Margin="3" Content="Move Down">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:CallMethodAction TargetObject="{Binding}"
MethodName="MoveDown" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</StackPanel>
<DataGrid Margin="3"
x:Name="DataGrid"
AutoGenerateColumns="False"
ItemsSource="{Binding Items, Mode=OneWay}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
CanUserAddRows="False"
CanUserDeleteRows="False"
IsReadOnly="True"
SelectionMode="Extended">
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="IsSelected"
Value="{Binding Path=IsSelected, Mode=TwoWay}" />
</Style>
</DataGrid.RowStyle>
<DataGrid.RowHeaderTemplate>
<DataTemplate>
<Grid>
<CheckBox Margin="3"
IsChecked="{Binding Path=IsSelected, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}}"
IsTabStop="False" />
</Grid>
</DataTemplate>
</DataGrid.RowHeaderTemplate>
</DataGrid>
</StackPanel>
我的相关VM代码
public ObservableCollection<ListItemViewModelBase<Person>> Items
{
get { return _items ?? (_items = new ObservableCollection<ListItemViewModelBase<Person>>()); }
}
public ListItemViewModelBase<Person> SelectedItem
{
get { return _selectedItem; }
set
{
if (_selectedItem == value)
return;
_selectedItem = value;
RaisePropertyChanged(() => SelectedItem);
}
}
public void MoveUp()
{
if (Items.Count(item => item.IsSelected) == 1)
{
// get it's index
int toMoveIndex = Items.IndexOf(SelectedItem);
// move up if not at zero
if (toMoveIndex > 0)
{
Items.Move(toMoveIndex, toMoveIndex - 1);
}
}
}
public void MoveDown()
{
if (Items.Count(item => item.IsSelected) == 1)
{
// get it's index
int toMoveIndex = Items.IndexOf(SelectedItem);
// move down if not at zero
if (toMoveIndex < Items.Count - 1)
{
Items.Move(toMoveIndex, toMoveIndex + 1);
}
}
}
公共可观察收集项目
{
获取{return\u items???(\u items=newobserveCollection());}
}
public ListItemViewModelBase SelectedItem
{
获取{return\u selectedItem;}
设置
{
如果(_selectedItem==值)
返回;
_选择editem=值;
RaisePropertyChanged(()=>SelectedItem);
}
}
公共空间向上移动()
{
if(Items.Count(item=>item.IsSelected)==1)
{
//获取它的索引
int-toMoveIndex=Items.IndexOf(SelectedItem);
//如果不在零,则向上移动
如果(toMoveIndex>0)
{
项目移动(toMoveIndex,toMoveIndex-1);
}
}
}
公共无效向下移动()
{
if(Items.Count(item=>item.IsSelected)==1)
{
//获取它的索引
int-toMoveIndex=Items.IndexOf(SelectedItem);
//如果不在零,则向下移动
if(toMoveIndex
以及Person和ListItemBase类
public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnProperyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
#region Fields
private string _firstName;
private Guid _id;
private string _lastName;
private int _sortOrder;
public int SortOrder
{
get { return _sortOrder; }
set
{
if (_sortOrder == value)
return;
_sortOrder = value;
OnProperyChanged("SortOrder");
}
}
public string FirstName
{
get { return _firstName; }
set
{
if (_firstName == value)
return;
_firstName = value;
OnProperyChanged("FirstName");
}
}
public string LastName
{
get { return _lastName; }
set
{
if (_lastName == value)
return;
_lastName = value;
OnProperyChanged("LastName");
}
}
public Guid Id
{
get { return _id; }
set
{
if (_id == value)
return;
_id = value;
OnProperyChanged("Id");
}
}
public static bool operator ==(Person item1, Person item2)
{
// if both null, equal
if (ReferenceEquals(item1, null) && ReferenceEquals(item2, null))
return true;
// if one null, one not, not equal
if (!ReferenceEquals(item1, null) && ReferenceEquals(item2, null))
return false;
if (ReferenceEquals(item1, null))
return false;
return item1.Equals(item2);
}
public static bool operator !=(Person item1, Person item2)
{
return !(item1 == item2);
}
public override string ToString()
{
return string.Format("{0} {1}: {2}", FirstName, LastName, SortOrder);
}
public override bool Equals(object obj)
{
var item = obj as Person;
if (item != null)
{
return Equals(item);
}
return base.Equals(obj);
}
public bool Equals(Person item)
{
if (item != null)
{
return GetHashCode() == item.GetHashCode();
}
return false;
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
}
public class ListItemViewModelBase<TModel> : ViewModelBaseExtended, IEquatable<ListItemViewModelBase<TModel>>
{
private bool _isSelected;
private TModel _model;
public ListItemViewModelBase(TModel model)
{
if (model == null)
{
throw new ArgumentNullException("model", "The model cannot be null.");
}
// set initial values
Model = model;
}
public static bool operator ==(ListItemViewModelBase<TModel> item1, ListItemViewModelBase<TModel> item2)
{
// if both null, equal
if (ReferenceEquals(item1, null) && ReferenceEquals(item2, null))
return true;
// if one null, one not, not equal
if (!ReferenceEquals(item1, null) && ReferenceEquals(item2, null))
return false;
if (ReferenceEquals(item1, null))
return false;
return item1.Equals(item2);
}
/// <returns></returns>
public static bool operator !=(ListItemViewModelBase<TModel> item1, ListItemViewModelBase<TModel> item2)
{
return !(item1 == item2);
}
public virtual bool IsSelected
{
get { return _isSelected; }
set { Set(() => IsSelected, ref _isSelected, value); }
}
public TModel Model
{
get { return _model; }
set { Set(() => Model, ref _model, value); }
}
public override string ToString()
{
return Model.ToString();
}
public override int GetHashCode()
{
return Model.GetHashCode();
}
public override bool Equals(object obj)
{
var item = obj as ListItemViewModelBase<TModel>;
if (item != null)
return Equals(item);
return base.Equals(obj);
}
public bool Equals(ListItemViewModelBase<TModel> other)
{
if (other != null)
{
// use Equals() here, not == because it's a Generic, == won't work
return Model.Equals(other.Model);
}
return false;
}
}
公共类人员:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
受保护的虚拟void onPropertyChanged(字符串propertyName)
{
if(PropertyChanged!=null)
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
#端区
#区域字段
私有字符串_firstName;
私有Guid _id;
私有字符串_lastName;
私人国际分拣机;
公共内部分拣机
{
获取{return\u sortOrder;}
设置
{
if(_sortOrder==值)
返回;
_排序器=值;
OnPropertyChanged(“排序器”);
}
}
公共字符串名
{
获取{return\u firstName;}
设置
{
if(_firstName==值)
返回;
_firstName=值;
OnPropertyChanged(“名字”);
}
}
公共字符串姓氏
{
获取{return\u lastName;}
设置
{
如果(_lastName==值)
返回;
_lastName=值;
OnPropertyChanged(“姓氏”);
}
}
公共Guid Id
{
获取{return\u id;}
设置
{
如果(_id==值)
返回;
_id=值;
OnPropertyChanged(“Id”);
}
}
公共静态布尔运算符==(个人项目1,个人项目2)
{
//如果两者都为null,则等于
if(ReferenceEquals(item1,null)和&ReferenceEquals(item2,null))
返回true;
//如果一个为空,那么一个不等于
如果(!ReferenceEquals(item1,null)和&ReferenceEquals(item2,null))
返回false;
if(ReferenceEquals(item1,null))
返回false;
返回项1。等于(项2);
}
公共静态布尔运算符!=(个人项目1,个人项目2)
{
返回!(item1==item2);
}
公共重写字符串ToString()
{
返回string.Format(“{0}{1}:{2}”,FirstName,LastName,SortOrder);
}
公共覆盖布尔等于(对象对象对象)
{
var项目=作为个人的obj;
如果(项!=null)
{
收益等于(项目);
}
返回基数等于(obj);
}
公共bool等于(个人项目)
{
如果(项!=null)
{
返回GetHashCode()==item.GetHashCode();
}
返回false;
}
公共覆盖int GetHashCode()
{
返回Id.GetHashCode();
}
}
公共类ListItemViewModelBase:ViewModelBaseExtended,IEquatable
{
私立学校当选;
私有TModel_模型;
公共ListItemViewModelBase(TModel模型)
{
if(model==null)
{
抛出新ArgumentNullException(“模型”,“模型不能为null”);
}
//设置初始值
模型=模型;
}
公共静态布尔运算符==(ListItemViewModelBase item1,ListItemViewModelBase item2)
{
//如果两者都为null,则等于
public void MoveUp()
{
if (Items.Count(item => item.IsSelected) == 1)
{
// create a list with the current items
var items = new List<ListItemViewModelBase<Person>>(Items);
// get the index of the item being moved
int oldIndex = items.IndexOf(SelectedItem);
// only move if the item isn't already at 0
if (oldIndex > 0)
{
// get the item we're moving
var item = items[oldIndex];
// remove the item from the list
items.RemoveAt(oldIndex);
// add the item back into the list at it's new position
items.Insert(oldIndex - 1, item);
// clear items list, and re-add items from our temp list
Items.Clear();
foreach (var toAdd in items)
{
Items.Add(toAdd);
}
}
}
}
public void MoveDown()
{
if (Items.Count(item => item.IsSelected) == 1)
{
// create a list with the current items
var items = new List<ListItemViewModelBase<Person>>(Items);
// get the index of the item being moved
int oldIndex = items.IndexOf(SelectedItem);
// only move if the item isn't already the last item
if (oldIndex < items.Count - 1)
{
// get the item we're moving
var item = items[oldIndex];
// remove the item from the list
items.RemoveAt(oldIndex);
// add the item back into the list at it's new position
items.Insert(oldIndex + 1, item);
// clear items list, and re-add items from our temp list
Items.Clear();
foreach (var toAdd in items)
{
Items.Add(toAdd);
}
}
}
}
ListViewAudio.RemoveAt(oldIndex);
ListViewAudio.Insert(newIndex, selectedItem);
ListViewAudio.Move(oldIndex, newIndex);