Как WPF связать динамически созданные флажки с динамически созданными сериями в LiveCharts? - PullRequest
0 голосов
/ 14 июня 2019

У меня есть liveChart, и я создаю флажки для каждого элемента в списке.Этот список также содержит данные для каждой серии в liveCharts.Как связать свои динамически созданные флажки с каждым отдельным LiveCharts.LineSeries из моих данных?

Я установил флажки:

<!-- Creating checkboxes by binding to list -->
<ListView ItemsSource="{Binding ElementItemList}" 
ScrollViewer.HorizontalScrollBarVisibility="Disabled" Width="600">
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel />
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>

            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Path=ElementName}" />
                        <CheckBox IsChecked="{Binding Path=ElementIsSelected}"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>

        </ListView>

<!-- Display the chart -->
<Grid Grid.Row="1" x:Name="TestGrid"></Grid>

1 Ответ

0 голосов
/ 19 июня 2019

Итак, я предполагаю, что вы хотите, чтобы CheckBox представлял каждый LineSeries в вашем SeriesCollection.

Таким образом, у меня было бы два public свойства, одно для SeriesCollection идругой для списка CheckBox элементов управления.

public SeriesCollection SeriesCollection { get; set; }
public List<CheckBox> CheckBoxCollection { get; set; }

Далее следует функция, которая имитирует динамическое создание элементов управления LineSeries и CheckBox, поскольку вы не предоставили этот код.Важно иметь какую-то связь между элементами управления CheckBox и вашей серией линий, и в этом случае я решил установить LineSeries.Title и CheckBox.Name одинаковыми.

Также обратите внимание, что длячтобы CheckBox что-то делал при проверке / снятии отметки, вам нужно зарегистрировать два события для каждого.

public void DynamicallyCreateStuff()
{
    SeriesCollection = new SeriesCollection();
    CheckBoxCollection = new List<CheckBox>();

    var count = 3;
    var val1 = new List<double>() { 1, 2, 3 };
    var val2 = new List<double>() { 9, 5, 3 };
    var val3 = new List<double>() { 1, 4, 9 };

    for (int i = 1; i <= count; i++)
    {
        var name = string.Format("LineSeries{0}", i);

        var checkBox = new CheckBox
        {
            Name = name,
            Content = name,
            Margin = new Thickness() { Left = 8, Top = 8, Right = 8, Bottom = 8 },
            IsChecked = true
        };
        checkBox.Checked += DynamicCheckBoxChecked;
        checkBox.Unchecked += DynamicCheckBoxUnchecked;
        CheckBoxCollection.Add(checkBox);

        var lineSeries = new LineSeries
        {
            Title = name
        };
        if (i == 1)
        {
            lineSeries.Values = new ChartValues<double>(val1);
        }
        else if (i == 2)
        {
            lineSeries.Values = new ChartValues<double>(val2);
        }
        else if (i == 3)
        {
            lineSeries.Values = new ChartValues<double>(val3);
        }

        SeriesCollection.Add(lineSeries);
    }
}

В моем случае я решил, что соответствующая серия станет видимой / скрытой при нажатииCheckBox, поэтому мои методы check / uncheck выглядят так:

private void DynamicCheckBoxChecked(object sender, EventArgs e)
{
    ShowHideSeries(sender, Visibility.Visible);
}

private void DynamicCheckBoxUnchecked(object sender, EventArgs e)
{
    ShowHideSeries(sender, Visibility.Collapsed);
}

private void ShowHideSeries(object sender, Visibility visibility)
{
    var checkBox = (CheckBox)sender;
    var found = SeriesCollection.FirstOrDefault(x => x.Title == checkBox.Name);
    if (found != null)
    {
        var series = (LineSeries)found;
        series.Visibility = visibility;
    }
}

Я не использовал ViewModel, чтобы сэкономить время и ради простоты, поэтому мои MainWindowКонструктор выглядит так:

public MainWindow()
{
    InitializeComponent();
    DynamicallyCreateStuff();
    DataContext = this;
}

И XAML здесь довольно голые кости:

<Window x:Class="SOLineCharts.MainWindow"
        ....
        xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
        mc:Ignorable="d"
        WindowStartupLocation="CenterScreen"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <ItemsControl Grid.Column="0" 
                      ItemsSource="{Binding CheckBoxCollection}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Vertical" ScrollViewer.HorizontalScrollBarVisibility="Disabled"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
        <lvc:CartesianChart Series="{Binding SeriesCollection}" Grid.Column="1"/>
    </Grid>
</Window>

Результат:

При загрузке:

enter image description here

Снятие одного флажка:

enter image description here

...