WPF 如何将动态创建的复选框绑定到 LiveCharts 中动态创建的系列?

How can I WPF bind dynamically created checkboxes to dynamically created series in LiveCharts?

我有一个实时图表,正在为列表中的每个项目创建复选框。此列表还包含 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>

所以我假设你想要一个 CheckBox 代表你 SeriesCollection 中的每个 LineSeries

所以我会有两个 public 属性,一个用于 SeriesCollection,另一个用于 CheckBox 控件列表。

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

下面是一个模拟动态创建 LineSeriesCheckBox 控件的函数,因为您没有提供该代码。在 CheckBox 控件和您的系列之间建立某种联系很重要,在这种情况下,我决定将 LineSeries.TitleCheckBox.Name 设置为相同。

另请注意,为了让 CheckBox 在 checking/unchecking 上执行某些操作,您需要为每个事件注册两个事件。

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 时将相应的系列变为 visible/hidden,所以我的 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>

结果:

加载时:

取消选中一个复选框: