Вот простая программа WPF (большая часть кода находится в коде):
MainWindow.xaml
* * 1004
<Window x:Class="WpfTextBlockInlineDataGridPSProcessSource.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfTextBlockInlineDataGridPSProcessSource"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</Window>
MainWindow.xaml.cs
using System.Diagnostics;
using System.Linq;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using static System.Console;
namespace WpfTextBlockInlineDataGridPSProcessSource
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var runspace = RunspaceFactory.CreateRunspace(InitialSessionState.CreateDefault());
runspace.Open();
var ps = PowerShell.Create();
ps.Runspace = runspace;
// var result = ps.AddScript("get-process").Invoke();
var result = ps.AddScript("get-process | select-object -first 20").Invoke();
WriteLine(result.Count);
if (result.All(elt => elt.BaseObject is Process))
{
var data_grid = new DataGrid()
{
ItemsSource = result,
IsReadOnly = true,
AutoGenerateColumns = false
};
data_grid.Columns.Add(new DataGridTextColumn()
{
Header = "ProcessName",
Binding = new Binding("ProcessName"),
});
var text_block = new TextBlock();
var scroll_viewer = new ScrollViewer();
scroll_viewer.Content = text_block;
text_block.Inlines.Add(data_grid);
text_block.Inlines.Add(new LineBreak());
var dock_panel = new DockPanel();
dock_panel.Children.Add(scroll_viewer);
Content = dock_panel;
}
}
}
}
Для создания этой тестовой программы вам понадобится пакет System.Management.Automation.dll nuget.
Вот как это выглядит при запуске:
Обратите внимание, что DataGrid
ItemsSource
установлен на результат команды PowerShell
.
В этом случае мы отображаем только 20 Process
объектов в DataGrid
.
Программа содержит всего 20 пунктов и быстро откликается.
Если мы изменим эту строку:
var result = ps.AddScript("get-process | select-object -first 20").Invoke();
на следующее:
var result = ps.AddScript("get-process").Invoke();
программа перестает отвечать на запросы. Обратите внимание, что в моей системе в списке более 370 процессов; результаты могут отличаться в вашей системе.
Как заставить программу реагировать на большое количество предметов?
Обратите внимание, что особое расположение элементов WPF:
DockPanel
-> ScrollViewer
-> TextBlock
-> Inline
-> DataGrid
предназначен для имитации другой программы, в которой эта предназначена для демонстрации проблемы. Вот почему она настроена таким образом.
Если в вашей системе недостаточно процессов для замедления, вы также можете использовать что-то вроде следующего:
var result = ps.AddScript("get-process | select-object -first 20; get-process | select-object -first 20; get-process | select-object -first 20").Invoke();
Для имитации большего числа процессов. (Рассмотрите возможность получения более 300.)