![](/img/trans.png)
[英]MVVM ObservableCollection inside a ObservableCollection (ViewModel)
[英]C# : public observablecollection<ViewModel> instance pass items to protected observablecollection<ViewModel>
我有下面的一課很好
public class RemoteSource {
ObservableCollection<RemoteDataViewModel> remote;
string[] _servers = new string[] {
"server",
"server",
"server",
"server",
"server"
};
public RemoteSource() {
remote = CreateDataSource();
}
protected ObservableCollection<RemoteDataViewModel> CreateDataSource() {
ObservableCollection<RemoteDataViewModel> res = new ObservableCollection<RemoteDataViewModel>();
ITerminalServicesManager _manager = new TerminalServicesManager();
foreach (var host in _servers) {
using (ITerminalServer srv = _manager.GetRemoteServer(host)) {
try {
srv.Open();
foreach (ITerminalServicesSession session in srv.GetSessions()) {
res.Add(new RemoteDataViewModel() { Server = srv.ServerName, SessionID = session.SessionId, UserID = session.UserName, State = session.ConnectionState, ConnectedTime = session.ConnectTime, LogonTime = session.LoginTime, IdleTime = session.IdleTime, UserIP = session.ClientIPAddress, Workstation = session.WindowStationName });
}
srv.Close();
}
catch (Win32Exception) { }
catch (SystemException) { }
catch (Exception) { }
}
}
return res;
}
/// <summary>
/// Gets the data.
/// </summary>
/// <value>
/// The data.
/// </value>
public ObservableCollection<RemoteDataViewModel> Data { get { return remote; } }
public ObservableCollection<string> hosts { get; set; }
}
已設置RemoteSource,但執行以下操作的按鈕事件
DataContext = new RemoteSource();
我想通讀具有服務器名稱列表的文本文件,如下所示
Server1
Server2
Server3
etc
並將它們加載到ObservableCollection中,然后能夠執行我目前在該行上所做的相同操作
foreach (var host in _servers) # but where _servers is the observablecollection initiated from the button event
我嘗試在按鈕事件下執行類似的操作,但是rs.hosts始終返回null
RemoteSource rs = new RemoteSource();
rs.hosts.Add(Environment.MachineName);
您的ObservableCollection<T>
應該是ViewModel的屬性。 然后,在視圖中,將一些ItemsControl.ItemsSource
屬性綁定到該視圖。
例如(超級簡化):
public class SessionViewModel : INotifyPropertyChanged
{
// ...
public ObservableCollection<String> ServerList { get; set; }
}
並在視圖中
<ListView x:Name="ServerList" ItemsSource="{Binding ServerList}"/>
不知道您是否要讓用戶選擇服務器或編輯服務器。 我都回答。 首先編輯,然后選擇。
綁定只能更新類的屬性。 它們不能用集合中另一種類型的完全不同的實例替換一種類型的實例。 那不是它的工作原理。 記住,這是Model View ViewModel 。 您的ViewModel必須公開其屬性綁定到UI中的元素的Model 。 這些屬性將通過綁定進行更新。
因此,為您的服務器創建一個模型
public sealed class ServerInfo
{
public string Name {get;set;}
public string IP {get;set;}
public string Whatevs {get;set;}
}
在您的VM中,您將通過ViewModel公開服務器列表。 如果要在選定的服務器上工作,則需要具有Selected屬性並在更新上工作。
public sealed class ViewModelLol : INotifyPropertyChanged
{
// init from ctor
public ObservableCollection<ServerInfo> Servers {get;private set;}
public ServerInfo SelectedServer {get;set;} // should be INPC impl, but yawn
// boring stuff goes here
}
在用戶界面中,您可以將ItemsSource綁定到集合
<ListBox ItemsSource="{Binding Servers}" SelectedItem="{Binding SelectedServer}" >
<ListBox.ItemTemplate>
<DataTemplate>
<!-- If you wanted to edit the server name... -->
<TextBox Text="{Binding Name}"/>
<!-- If you only care about selection... -->
<Label Content="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
不確定是否要編輯服務器名稱,如果是這樣,請使用第一個選項。 如果要向用戶顯示服務器列表並允許他們選擇服務器,請使用標簽選項。
用戶選擇服務器后,將更新ViewModel中的SelectedServer
。 您可以利用這個機會來做所需的任何工作。
ViewModels應該位於邏輯食物鏈的頂部。 它們解釋系統用戶的操作,並將其轉換為其中的API調用。 因此,如果您需要連接到服務器,則VM應該包含連接到服務器的邏輯。 VM不應是某些業務邏輯類的子級。 這需要一些棘手的意大利面條代碼,將很難實現。
虛擬機應該位於UI和您的核心業務邏輯之間,根本不關心UI。 例如,連接到服務器與UI無關。 確定要連接的服務器。 縮小這一差距是虛擬機的作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.