2013-03-10 124 views
0

我有一个异步服务器侦听本地网络上的客户端。当每个客户端向服务器发送连接消息时,我希望服务器在表中显示客户端的名称。如何将表格/网格添加到vb.net/C# WPF窗口?

假设我已经有客户端名称和IP地址作为字符串ClientDetails用_分隔“PC5_192.168.1.10”

* 编辑*

我想要什么

随着客户加盟,我想每一个客户作为新行添加到表/格。

我正在使用WPF。无论是vb.net或C#的答案都会很好,我可以自己翻译它。

+1

1 - 如果您使用的是WPF。标记你的问题WPF。 2 - 请不要将WPF'Window'称为“表单”。这是对我的信仰和价值的侮辱。3 - “DataGrid”与数据库无关。 – 2013-03-10 14:58:00

+0

@HighCore竖起你的评论! :) – 2013-03-10 14:58:47

+0

我现在称之为“窗口”,以帮助降低血压 – 2013-03-10 14:59:36

回答

2

我准备了一个“WPF方式”的小例子来做到这一点。 它看起来像这样在我的电脑:

enter image description here

进出口使用随机值作为数据源:我通过使用Action<Connection>委托给加了一个间接层

public class RandomConnectionAdder 
    { 
     public Timer timer; 
     public Random random = new Random(); 

     public Action<Connection> OnConnectionAdded { get; set; } 

     public RandomConnectionAdder(Action<Connection> onConnectionAdded) 
     { 
      OnConnectionAdded = onConnectionAdded; 
      timer = new Timer(x => AddConnection(), null, 5000, 2000); 
     } 

     private void AddConnection() 
     { 
      var computernumber = random.Next(1, 50); 
      var newrandomconnection = new Connection() 
       { 
        ComputerName = "PC" + computernumber.ToString(), 
        IPAddress = "192.168.1." + computernumber, 
        ConnectionTime = DateTime.Now 
       }; 

      if (OnConnectionAdded != null) 
       OnConnectionAdded(newrandomconnection); 
     } 
    } 

公告保持顾虑的分离。 “监听者”负责监听传入连接,添加新连接时应该怎么做不在其范围之内。

这是模型类:

public class Connection: INotifyPropertyChanged 
    { 
     private string _computerName; 
     public string ComputerName 
     { 
      get { return _computerName; } 
      set 
      { 
       _computerName = value; 
       OnPropertyChanged("ComputerName"); 
      } 
     } 

     private string _ipAddress; 
     public string IPAddress 
     { 
      get { return _ipAddress; } 
      set 
      { 
       _ipAddress = value; 
       OnPropertyChanged("IPAddress"); 
      } 
     } 

     private DateTime _connectionTime; 
     public DateTime ConnectionTime 
     { 
      get { return _connectionTime; } 
      set 
      { 
       _connectionTime = value; 
       OnPropertyChanged("ConnectionTime"); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     protected virtual void OnPropertyChanged(string propertyName) 
     { 
      PropertyChangedEventHandler handler = PropertyChanged; 
      if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

这是在Window代码隐藏:

public partial class Window6 : Window 
    { 
     private RandomConnectionAdder adder; 
     private ObservableCollection<Connection> Connections; 

     public Window6() 
     { 
      InitializeComponent(); 
      Connections = new ObservableCollection<Connection>(); 
      adder = new RandomConnectionAdder(x => Dispatcher.BeginInvoke((Action) (() => AddConnection(x)))); 
      DataContext = Connections; 
     } 

     private void AddConnection(Connection connection) 
     { 
      Connections.Add(connection); 
     } 
    } 

正如你可以看到,该窗口实例化RandomConnectionAdder,并将其OnConnectionAdded行动拉姆达通过Dispatcher将该项目添加到ObservableCollection UI线程。

最后,这是整个XAML:

<Window x:Class="WpfApplication5.Window6" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="Window6" Height="300" Width="300"> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition/> 
      <ColumnDefinition/> 
      <ColumnDefinition/> 
     </Grid.ColumnDefinitions> 

     <GroupBox Header="DataGrid"> 
      <DataGrid ItemsSource="{Binding}" AutoGenerateColumns="False" IsReadOnly="True"> 
       <DataGrid.Columns> 
        <DataGridTextColumn Header="Computer Name" Binding="{Binding ComputerName}"/> 
        <DataGridTextColumn Header="IP Address" Binding="{Binding IPAddress}"/> 
        <DataGridTextColumn Header="Connection Time" Binding="{Binding ConnectionTime, StringFormat='HH:mm:ss'}"/> 
       </DataGrid.Columns> 
      </DataGrid> 
     </GroupBox> 

     <GroupBox Header="Large Icons (ListBox)" Grid.Column="1"> 
      <ListBox ItemsSource="{Binding}"> 
       <ListBox.Template> 
        <ControlTemplate> 
         <ItemsPresenter/> 
        </ControlTemplate> 
       </ListBox.Template> 
       <ListBox.ItemTemplate> 
        <DataTemplate> 
         <DockPanel Margin="5" Width="120"> 
          <StackPanel DockPanel.Dock="Bottom"> 
           <TextBlock Text="{Binding ComputerName}" TextAlignment="Center"/> 
           <TextBlock Text="{Binding IPAddress}" TextAlignment="Center"/> 
           <TextBlock Text="{Binding ConnectionTime, StringFormat='HH:mm:ss'}" TextAlignment="Center"/> 
          </StackPanel> 
          <Border Height="60" Width="60" BorderBrush="Black" BorderThickness="1"> 
           <TextBlock Text="Some Icon" VerticalAlignment="Center" TextAlignment="Center"/> 
          </Border> 
         </DockPanel> 
        </DataTemplate> 
       </ListBox.ItemTemplate> 
       <ListBox.ItemsPanel> 
        <ItemsPanelTemplate> 
         <WrapPanel IsItemsHost="True"/> 
        </ItemsPanelTemplate> 
       </ListBox.ItemsPanel> 
      </ListBox> 
     </GroupBox> 

     <GroupBox Header="Tiles (ListBox)" Grid.Column="2"> 
      <ListBox ItemsSource="{Binding}"> 
       <ListBox.Template> 
        <ControlTemplate> 
         <ItemsPresenter/> 
        </ControlTemplate> 
       </ListBox.Template> 
       <ListBox.ItemTemplate> 
        <DataTemplate> 
         <DockPanel Margin="5" Width="120"> 
          <Border Height="40" Width="50" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Left"> 
           <TextBlock Text="Some Icon" VerticalAlignment="Center" TextAlignment="Center"/> 
          </Border> 
          <StackPanel> 
           <TextBlock Text="{Binding ComputerName}" TextAlignment="Center"/> 
           <TextBlock Text="{Binding IPAddress}" TextAlignment="Center"/> 
           <TextBlock Text="{Binding ConnectionTime, StringFormat='HH:mm:ss'}" TextAlignment="Center"/> 
          </StackPanel> 
         </DockPanel> 
        </DataTemplate> 
       </ListBox.ItemTemplate> 
       <ListBox.ItemsPanel> 
        <ItemsPanelTemplate> 
         <WrapPanel IsItemsHost="True"/> 
        </ItemsPanelTemplate> 
       </ListBox.ItemsPanel> 
      </ListBox> 
     </GroupBox> 

    </Grid> 
</Window> 

正如你所看到的而言,我没有办法操纵代码UI元素。这使得代码干净简单,并且很好地分离,因为应用程序逻辑/数据决不依赖于UI元素的状态。

此外,在这个例子中可以看到“将几个不同的视图绑定到相同的ViewModel”的概念,在这种情况下是ObservableCollection本身。

这是一切的“WPF”方法。您几乎不需要在代码中操作UI元素,至少不会考虑应用程序逻辑或数据。

只需将我的代码复制并粘贴到File -> New Project -> WPF Application中即可自行查看结果。

+0

喔!这是一个verrrrry详细的答案! A ++ ..我会试试这个。 – 2013-03-10 16:01:36

+0

好的答案队友! – failedprogramming 2013-03-10 23:45:18