2011-09-25 53 views
0

好的,所以我试图在我的应用程序中实现一个相当简单的功能。我想有一个正在运行的进程列表(按其进程名称,ID列出),当我点击列表中的一个进程时,更新一些标签,其中包含关于该进程的信息(同样,进程名称,ID等)那)。问题绑定到WPF列表框的进程数组

在查看DataBinding与MSDN的MSDN文档后,我创建了自己的自定义类ProcessList,它继承自ObservableCollection。这个类现在完全是裸露的,我之前一直在试图让事情发挥作用,所以我想我可能只是直接用ObservableCollection工作,但无论如何。以下是我目前所面对的:

public partial class MainWindow : Window 
    { 
     private Dictionary<int, Injector> injectors; 
     public Process[] processes; 
     public ProcessList procList; 

     public MainWindow() 
     { 
      procList = new ProcessList(); 
      foreach (var p in Process.GetProcesses()) 
      { 
       procList.Add(p); 
      } 
      InitializeComponent(); 
      processGrid.DataContext = procList; 
     } 

     private void button_refresh_processes_Click(object sender, RoutedEventArgs e) 
     { 
      processes = Process.GetProcesses(); 
     } 
    } 
} 

和配属XAML:

<Grid Name="processGrid" Margin="0,21,0,0"> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="348*" /> 
         <ColumnDefinition Width="145*" /> 
        </Grid.ColumnDefinitions> 
        <Grid.RowDefinitions> 
         <RowDefinition Height="147*" /> 
         <RowDefinition Height="42*" /> 
        </Grid.RowDefinitions> 
        <Button Content="Inject" Grid.Row="1" Height="23" HorizontalAlignment="Center" Margin="0,0,0,0" Name="button_inject" VerticalAlignment="Center" Width="75" /> 
        <ListBox Height="147" HorizontalAlignment="Left" Name="process_list" VerticalAlignment="Top" Width="348" ItemsSource="{Binding Path=ProcessName}" /> 
        <Grid Grid.Column="1" Height="147" HorizontalAlignment="Left" Name="grid2" VerticalAlignment="Top" Width="145"> 
         <Grid.RowDefinitions> 
          <RowDefinition Height="1*" /> 
          <RowDefinition Height="1*" /> 
          <RowDefinition Height="1*" /> 
          <RowDefinition Height="1*" /> 
         </Grid.RowDefinitions> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="1*" /> 
          <ColumnDefinition Width="1*" /> 
         </Grid.ColumnDefinitions> 
         <Label Content="Process ID:" Grid.RowSpan="1" Height="28" HorizontalAlignment="Left" Margin="0" Name="label_pid" VerticalAlignment="Center" /> 
         <Label Content="PID" Grid.Column="1" Grid.RowSpan="1" Height="28" HorizontalAlignment="Right" Margin="0" Name="label_pid_value" VerticalAlignment="Center" /> 
        </Grid> 
        <Button Content="Refresh" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="6,9,0,0" Name="button_refresh_processes" VerticalAlignment="Top" Width="75" Click="button_refresh_processes_Click" /> 
       </Grid> 

我目前遇到的问题是,不是显示由他们ProcessName所有正在运行的进程的列表,而是将第一个进程的名称中的每个字符看作是列表中的单独条目,而没有其他内容。 Screenshot

我不知道发生了什么,虽然我确信我正在做一些非常愚蠢的事情,因为我对WPF开发和数据绑定非常陌生。

回答

1

我想知道为什么你会得到一个输出。

ItemsSource="{Binding Path=ProcessName}" 

表示项目的来源是ProcessName。该名称是一个字符串,字符串是IEnumerable<Char>。所以列表框显示每个字符作为一个条目。

您必须将ItemsSource设置为列表本身。在你的情况下,将

ItemsSource="{Binding}" 

因为ProcessList已经是你的网格,被继承到列表框的数据上下文。

如果您未使用视图模型类(这是使用MVVM模式时的最佳做法),则可以在您的Windows构造函数中执行DataContext = this;以将窗口的数据上下文设置为其自己的代码隐藏。如果你这样做你的列表的结合将改变以

ItemsSource="{Binding procList}" 

然而,你应该出台一个属性,实现INotifyPropertyChanged让你的UI通知和数据源改变时进行更新。

TL; DR版本:如果您想充分利用WPF,需要查看XAML/Bindings指南和MVVM模式。

+0

感谢您的回复。我会进一步研究MVVM模式,之前已经听说过它,但从来没有详细研究它。当我实现你的更改并将其作为'ItemsSource =“{Binding}”'列表填充,但没有任何条目有任何文本,任何想法如何去解决这个问题? –

+2

这是因为你应该在你的ComboBox中设置一个DisplayMemberPath =“ProcessName”......(假设ProcessName是属性,代表了Process类中的进程名) –