Я тестирую Rx. net или вообще реактивные расширения, поэтому в моем приложении WPF у меня есть сетка данных, содержащая до 1 миллиона строк.
Моя цель - предоставить настройка цвета фона строки Dynami c на основе ввода текстового поля и выбора цвета из палитры цветов (здесь я использую https://github.com/PropertyTools/PropertyTools Color Picker).
Текущее поведение приложения можно увидеть в этом gif:
поведение приложения
Соответствующая часть кода, которая выполняет работу, выглядит следующим образом:
public class MainViewModel : ReactiveObject
{
[Reactive] public string SearchPhrase { get; set; } = "0";
[Reactive] public Color ColorPickerSelectedColor { get; set; }
private readonly ReadOnlyObservableCollection<DataGridViewModel> _itemsBinding;
private IObservable<IChangeSet<DataGridViewModel>> _dataListObservable;
public ReadOnlyObservableCollection<DataGridViewModel> TargetCollection => _itemsBinding;
public MainViewModel(SourceList<DataGridViewModel> _dataList)
{
AddSomeRandomData(_dataList);
_dataListObservable = _dataList.Connect();
_dataListObservable.ObserveOn(RxApp.MainThreadScheduler)
.Bind(out _itemsBinding)
.DisposeMany()
.Subscribe();
this.WhenAnyValue(p1 => p1.ColorPickerSelectedColor, p2 => p2.SearchPhrase)
.Throttle(TimeSpan.FromMilliseconds(250), RxApp.TaskpoolScheduler)
.ObserveOn(RxApp.TaskpoolScheduler)
.Subscribe(_ =>
{
_dataListObservable.AsObservableList().Items.ForEach(item => {
item.BackgroundColor = item.Id.Equals(SearchPhrase, StringComparison.OrdinalIgnoreCase) ? ColorPickerSelectedColor : default;
});
});
}
private void AddSomeRandomData(SourceList<DataGridViewModel> _dataList)
{
var random = new Random();
for (int i = 0; i < 1e6; i++)
{
var buffer = new byte[random.Next(1, 80)];
random.NextBytes(buffer);
string hexData = BitConverter.ToString(buffer);
int randomId = random.Next(1, 10);
var dataGridViewModel = new DataGridViewModel
{
TimeStamp = DateTime.Now.ToString("HH:mm:ss.ffffff"),
Id = randomId.ToString(),
HexData = hexData,
BackgroundColor = ColorPickerSelectedColor
};
_dataList.Add(dataGridViewModel);
}
}
}
Хотя приложение работает, как ожидалось, я думаю, что я реализовал настройку цвета фона, эта часть:
this.WhenAnyValue(p1 => p1.ColorPickerSelectedColor, p2 => p2.SearchPhrase)
.Throttle(TimeSpan.FromMilliseconds(250), RxApp.TaskpoolScheduler)
.ObserveOn(RxApp.TaskpoolScheduler)
.Subscribe(_ =>
{
_dataListObservable.AsObservableList().Items.ForEach(item => {
item.BackgroundColor = item.Id.Equals(SearchPhrase, StringComparison.OrdinalIgnoreCase) ? ColorPickerSelectedColor : default;
});
});
немного не так.
Может кто-нибудь показать мне лучший способ сделать это?
Части xaml:
DataGridControl
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:reactivedatagridtest="clr-namespace:ReactiveDataGridTest"
x:Class="ReactiveDataGridTest.Ressources.DataGridControl">
<DataGrid ItemsSource="{Binding TargetCollection}"
x:Key="MainTracingDataGrid"
x:Name="TracingDataGrid"
ScrollViewer.ScrollChanged="TracingDataGrid_ScrollChanged"
EnableRowVirtualization="True"
RowHeight="40"
AutoGenerateColumns="False">
<DataGrid.Resources>
<reactivedatagridtest:ColorToSolidColorBrushValueConverter x:Key="ColorToSolidColorBrush_ValueConverter"/>
<Style TargetType="DataGridRow">
<Setter Property="Background" Value="{Binding BackgroundColor, Converter={StaticResource ColorToSolidColorBrush_ValueConverter}}"/>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Header="Timestamp" Binding="{Binding TimeStamp}"/>
<DataGridTextColumn Header="Id" Binding="{Binding Id}"/>
<DataGridTextColumn Header="Data" Binding="{Binding HexData}"/>
</DataGrid.Columns>
</DataGrid>
</ResourceDictionary>
MainWindow
<Window x:Class="ReactiveDataGridTest.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:ReactiveDataGridTest"
xmlns:p="clr-namespace:PropertyTools.Wpf;assembly=PropertyTools.Wpf"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Ressources/DataGridControl.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ToolBar Grid.Row="0">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<materialDesign:PackIcon Kind="Search"/>
<TextBox Width="150" Text="{Binding SearchPhrase, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
<Separator/>
<p:ColorPicker SelectedColor="{Binding ColorPickerSelectedColor}" />
</ToolBar>
<ContentControl Content="{StaticResource MainTracingDataGrid}" Grid.Row="1"/>
</Grid>
</Window>