问题将进程数组绑定到WPF ListBox

时间:2011-09-25 20:43:26

标签: c# wpf xaml data-binding

好的,所以我试图在我的应用中实现一个相当简单的功能。我希望有一个正在运行的进程列表(按进程名称,ID列出等),当我单击列表中的进程时,更新一些标签,其中包含有关该进程的信息(同样,进程名称,ID,类似于这一点)。

在查看带有集合的DataBinding的MSDN文档之后,我创建了自己的继承自ObservableCollection的自定义类ProcessList。这个课程现在已经完全裸露了,我以前一直在努力解决这个问题,所以我想我也可以直接使用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 个答案:

答案 0 :(得分:1)

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

ItemsSource="{Binding Path=ProcessName}"

表示项目的来源是ProcessName。名称是字符串,字符串是IEnumerable<Char>。因此列表框将每个char显示为一个条目。

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

ItemsSource="{Binding}"

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

如果您没有使用视图模型类(这是使用MVVM模式时的最佳实践),您可以在Windows构造函数中执行DataContext = this;以将窗口的数据上下文设置为其自己的代码 - 背后。如果这样做,列表的绑定将更改为

ItemsSource="{Binding procList}"

但是,您应该引入一个属性并实现INotifyPropertyChanged,以便在数据源发生更改时通知并更新您的UI。

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