![](/img/trans.png)
[英]How can I highlight a DataGrid row programmatically from the ViewModel alone?
[英]How to select a row in datagrid from ViewModel in MVVM?
我正在嘗試驗證數據網格中的用戶輸入,我這樣做的方式如下:
I)允許用戶添加一行
II)允許用戶填寫一些單元格
III)當EndEdit()事件發生時,我會更新我的模型
IV)如果模型無法更新(例如,當用戶未提供NotNull值時),則會引發錯誤。
V)這里是特技部分! 我想留在datagrid的錯誤行上,但是盡管我已經正確設置了SelectedIndex和SelectedValue,但高亮行會發生變化。
這是我的XAML:
<DataGrid x:Name="gd_Contacts" SelectedItem="{Binding SelectedContact,Converter={StaticResource NewPlaceConverter}}"
SelectedIndex="{Binding SelectedItemIndex}"
Margin="0,5,1,0" ItemsSource="{Binding ContactCollection, Mode=TwoWay}"
CanUserAddRows="True" CanUserDeleteRows="False" AutoGenerateColumns="False" Grid.Column="1">
這是我的ViewModel:
private ObservableCollection<ActionEnabledContacts> FContactCollection;
//....
public ActionEnabledContacts SelectedContact //THE PROPERTY FOR SELECTEDITEM
{
get { return FSelectedContact; }
set
{
//
List <ActionEnabledContacts> InvalidList=ContactCollection.Where<ActionEnabledContacts>(p => p.cnt_Key == 0).ToList();
if (InvalidList != null && InvalidList.Count > 0)
{
//now find index of that bastard
List<ActionEnabledContacts> AllContacts = ContactCollection.ToList();
int BastardIndex = 0;
foreach (ActionEnabledContacts AContact in AllContacts)
{
if (AContact.cnt_Key == 0)
{
FSelectedContact = InvalidList[0];
NotifyPropertyChanged();
SelectedItemIndex = BastardIndex;
//^^^^ THIS LINE DO UPDATE SELECTEDINDEX AND CALL NotifyPropertyChanged()
}
BastardIndex++;
}
}
else
{
//
FSelectedContact = value;
NotifyPropertyChanged();
}
}
}
當選擇發生變化時,您無法更改選擇...如果有任何意義:P
如果選擇剛剛更改,您將不得不等到可以再次以編程方式更改它。 這通常使用Dispatcher.BeginInvoke
將您的調用添加到Dispatcher隊列,因此它在處理當前選擇后執行。
if (AContact.cnt_Key == 0)
{
FSelectedContact = InvalidList[0];
NotifyPropertyChanged();
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
SelectedItemIndex = BastardIndex));
}
BastardIndex++;
但是在viewmodel中執行此操作並不是最佳解決方案 - 無論是MVVM還是多UI線程方案。 您可以簡單地在該行中引發一個事件(在EventArgs
傳遞索引),讓您的視圖訂閱該事件,並從事件處理程序this.Dispatcher
Dispatcher調用(使用this.Dispatcher
而不是Application.Current.Dispatcher
)。
感謝@almulo,我在ViewModel中實現了一個事件,並在View中實現了相應的處理程序,它就像一個魅力,對於那些可能需要幫助的人來說,這些是以下步驟:
I)在ViewModel中添加如下事件 :
public event EventHandler<EventArg<int>> DataGridRowSelectionChange;
*請注意,EventArg只是一個可以保存T類型值的簡單類,如下所示:
public class EventArg<T> : EventArgs
{
private T FEventData;
public EventArg(T Param)
{
// TODO: Complete member initialization
FEventData = Param;
}
public T EventData
{
get { return FEventData; }
set { FEventData = value; }
}
}
II)每當您想要更改所選行時,在ViewModel中 :
if (DataGridRowSelectionChange != null)
DataGridRowSelectionChange(this, new EventArg<int>(DesiredIndex));
III)在View構造函數中添加事件處理程序 ,如下所示:
((YourViewModelClass)DataContext).DataGridRowSelectionChange += CurrentViewModel_DataGridRowSelectionChange_EventHandler;
IV)最后在View中編寫處理程序,如下所示:
void CurrentViewModel_DataGridRowSelectionChange_EventHandler(object sender, EventArg<int> e)
{
Dispatcher.BeginInvoke(new Action(() => GRIDNAME.SelectedIndex = e.EventData));
}
就這樣 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.