C#:公共observablecollection< ViewModel>实例将项目传递给受保护的observablecollection< ViewModel>. [英] C# : public observablecollection<ViewModel> instance pass items to protected observablecollection<ViewModel>

查看:123
本文介绍了C#:公共observablecollection< ViewModel>实例将项目传递给受保护的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,但执行以下操作的按钮事件

The RemoteSource is setup but a button event that does the following

DataContext = new RemoteSource();

我想通读具有服务器名称列表的文本文件

I want to read through a text file that has the list of server names like so

Server1
Server2
Server3
etc

并将它们加载到ObservableCollection中,然后可以执行我在此行上当前正在做的相同的事情

and load them into an ObservableCollection then be able to do the same thing I am currently doing on this line

foreach (var host in _servers) # but where _servers is the observablecollection initiated from the button event

我尝试在button事件下执行类似的操作,但是rs.hosts始终返回null

I attempted doing something like this under the button event, but rs.hosts always returns as null

RemoteSource rs = new RemoteSource();
rs.hosts.Add(Environment.MachineName);

推荐答案

不确定是否要让用户选择服务器或编辑服务器.我都在回答.首先编辑,然后选择.

Not sure if you're trying to let the user select a server, or edit the server. I'm answering both. Editing first, then selecting after.

绑定只能更新类的属性.它们不能用集合中另一种类型的完全不同的实例替换一种类型的实例.那不是它的工作原理.请记住,这是 Model View ViewModel .您的ViewModel必须公开其属性绑定到UI中的元素的 Model .这些属性将通过绑定进行更新.

Bindings can only update properties of a class. They cannot replace an instance of one type with a completely different instance of another type within a collection. That's just not how it works. Remember, this is Model View ViewModel. Your ViewModels must expose Models whose properties are bound to elements in the UI. These properties will be updated by the bindings.

因此,为您的服务器创建一个模型

So, create a Model for your server

public sealed class ServerInfo
{
    public string Name {get;set;}
    public string IP {get;set;}
    public string Whatevs {get;set;}
}

在您的VM中,您将通过ViewModel公开服务器列表.如果您希望在选定的服务器上工作,那么您希望拥有一个Selected属性并在更新上工作.

In your VM, you would expose your list of servers from the ViewModel. If you're looking to do work on selected servers, you'd want to have a Selected property and do work on update.

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绑定到集合

In your UI, you'd bind an ItemsSource to the collection

<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>

不确定是否要编辑服务器名称,如果是这样,请使用第一个选项.如果要向用户显示服务器列表并允许他们选择服务器,请使用标签选项.

Not exactly sure if you want to be able to edit the server name, if so, use the first option. If you want to present to the user a list of servers and allow them to select one, then use the label option.

一旦用户选择了服务器,ViewModel中的SelectedServer就会更新.您可以借此机会做任何需要做的工作.

Once the user selects a server, SelectedServer in the ViewModel is updated. You can take that opportunity to do whatever work you need to.

ViewModels应该位于逻辑食物链的顶部.它们解释系统用户的操作,并将其转换为其中的API调用.因此,如果您需要连接到服务器,则VM应该包含连接到服务器的逻辑. VM不应是某些业务逻辑类的子级.这需要一些棘手的意大利面条代码,并且将很难实现.

ViewModels should be at the top of the logic food chain. They interpret actions of users of the system and convert them into API calls within. So if you need to connect to a server, then the VM should contain the logic to connect to the server. The VM shouldn't be a child of some business logic class. That requires some tricky spaghetti code and will be harder to implement.

虚拟机应该位于UI和您的核心业务逻辑之间,根本不关心UI.例如,连接到服务器与UI无关.确定要连接的服务器.缩小差距就是虚拟机的作用.

VMs are supposed to sit between the UI and your core business logic, which shouldn't care about the UI at all. For instance, connecting to a server has nothing to do with the UI. Identifying which server to connect to does. Bridging that gap is the role of the VM.

这篇关于C#:公共observablecollection&lt; ViewModel&gt;实例将项目传递给受保护的observablecollection&lt; ViewModel&gt;.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆