0
votes
<MultiBinding Converter="{StaticResource DifferenceConverter}">
        <Binding Path="[1].Value" />
        <Binding Path="[0].Value" />
</MultiBinding>

I have list List<List<KeyValuePair<string, int>>> which i bind to DataContext of WPF Toolkit chart.

Every item in list - new ColumnSerie and binding I try to apply only to last serie

What i need - correctly use MultiBinding (Don't know how to write correct path to values of first and second items in list).

Also tried smth like [1]/Value - unsuccess.


UPDATE (Detailed Explanation):

As i wrote before, i have chart with few columnSeries (really only 2). I bind List<List<KeyValuePair<string, int>>> (size = 2) to chart DataContext and in XAML init ColumnSeries like ItemsSource="{Binding [1]}"

For Second ColumnSeries I create Style :

<Style x:Key="ColumnDataPointStyle1" TargetType="{x:Type chartingToolkit:ColumnDataPoint}">
        <Setter Property="Background" Value="#61596f" />
        <Setter Property="BorderBrush" Value="#61596f" />
        <Setter Property="BorderThickness" Value="100" />
        <Setter Property="IsTabStop" Value="False" />
        <Setter Property="Padding" Value="0" />
        <Setter Property="Margin" Value="0"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type chartingToolkit:ColumnDataPoint}">
                    <Grid>
                        <Rectangle Fill="{TemplateBinding Background}" />
                        <TextBlock  Foreground="White" FontSize="8" FontWeight="Bold" HorizontalAlignment="Center" VerticalAlignment="Center"> 
                            <TextBlock.Text>
                                <MultiBinding Converter="{StaticResource DifferenceConverter}">
                                    <Binding ElementName="FirstScan" Path="ItemsSource[0].Value"/>
                                    <Binding Path="Value" />
                                </MultiBinding>
                            </TextBlock.Text>   
                        </TextBlock>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

And Converter :

public class DifferenceConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var diff = (int) values[1] - (int) values[0];
        if (diff > 0)
        {
            return "<";
        }
        if (diff < 0)
        {
            return ">";
        }
        return "none";
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

This converter should show difference between column value in first and second series. If first value is greater than second - ">" else "<", if Equal - "none" etc. Problem - need to bind values from first ColumnSeries.

1
[0] would give you first List<KeyValuePair<string, int>>, and [0].[0] will give you first KeyValuePair ever in the entire List, [0].[0].Value should give you your first ever KeyValuePair's value.AnjumSKhan
@AnjumSKhan, thanks, now i get it. But one more problem (please check update in question) i need to bind values from another control (columnSerie)demo
no idea about that toolkit, but you can use this codeproject.com/Articles/196502/…AnjumSKhan

1 Answers

0
votes

Xaml:

        <TextBlock>
            <TextBlock.Text>
                <MultiBinding Converter="{StaticResource MultiBindingConverter}">
                    <Binding Path="[0][0].Value" />
                    <Binding Path="[0][1].Value" />
                    <Binding Path="[0][2].Value" />
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>

C# Converter:

public class MultiBindingConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        int value1 = (int)values[0];
        int value2 = (int)values[1];
        int value3 = (int)values[2];



        return null;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

====================================== Update

Xaml:

<Window x:Class="WpfToolkitChart.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfToolkitChart"
    xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"

    Title="MainWindow" Height="1031" Width="855" 
    >

<Window.Resources>

    <local:DifferenceConverter x:Key="DifferenceConverter" />

    <Style x:Key="ColumnDataPointStyle1" TargetType="{x:Type chartingToolkit:ColumnDataPoint}">
        <Setter Property="Background" Value="#61596f" />
        <Setter Property="BorderBrush" Value="#61596f" />
        <Setter Property="BorderThickness" Value="100" />
        <Setter Property="IsTabStop" Value="False" />
        <Setter Property="Padding" Value="0" />
        <Setter Property="Margin" Value="0"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type chartingToolkit:ColumnDataPoint}">
                    <Grid>
                        <Rectangle Fill="{TemplateBinding Background}" />
                        <TextBlock  Foreground="White" FontSize="8" FontWeight="Bold" HorizontalAlignment="Center" VerticalAlignment="Top">
                            <TextBlock.Text>
                                <MultiBinding Converter="{StaticResource DifferenceConverter}">

                                    <!--Get firstScan all item-->
                                    <Binding ElementName="FirstScan" Path="ItemsSource"/>

                                    <!--Get secondScan all item-->
                                    <Binding ElementName="SecondScan" Path="ItemsSource"/>

                                    <!--Get secondScan current KeyValuePair-->
                                    <Binding Path="" />

                                </MultiBinding>
                            </TextBlock.Text>
                        </TextBlock>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</Window.Resources>

<Grid>

    <chartingToolkit:Chart Height="262" 
                            Name="columnChart" 
                            Title="Column Series Demo" 
                            >


        <chartingToolkit:ColumnSeries x:Name="FirstScan"
                                        DependentValuePath="Value" 
                                        IndependentValuePath="Key"
                                        ItemsSource="{Binding [0]}"
                                        />

        <chartingToolkit:ColumnSeries x:Name="SecondScan"
                                        DependentValuePath="Value" 
                                        IndependentValuePath="Key"
                                        ItemsSource="{Binding [1]}"
                                        DataPointStyle="{StaticResource ColumnDataPointStyle1}"
                                        >

        </chartingToolkit:ColumnSeries>

    </chartingToolkit:Chart>

</Grid>

C#:

public partial class MainWindow : Window
{
    public List<List<KeyValuePair<string, int>>> ViewModel { get; private set; }

    public MainWindow()
    {
        InitializeComponent();
        DataContextChanged += MainWindow_DataContextChanged;

        var viewModel = new List<List<KeyValuePair<string, int>>>();

        for (int f = 0; f < 1; f++)
        {
            var item = new List<KeyValuePair<string, int>>();

            item.Add(new KeyValuePair<string, int>($"{f}, Key1", 1));
            item.Add(new KeyValuePair<string, int>($"{f}, Key2", 2));
            item.Add(new KeyValuePair<string, int>($"{f}, Key3", 3));

            viewModel.Add(item);
        }

        for (int f = 1; f < 2; f++)
        {
            var item = new List<KeyValuePair<string, int>>();

            item.Add(new KeyValuePair<string, int>($"{f}, Key2", 2));
            item.Add(new KeyValuePair<string, int>($"{f}, Key1", 1));
            item.Add(new KeyValuePair<string, int>($"{f}, Key3", 3));

            viewModel.Add(item);
        }


        DataContext = viewModel;
    }

    private void MainWindow_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        ViewModel = DataContext as List<List<KeyValuePair<string, int>>>;
    }

    private void ButtonAdd_Click(object sender, RoutedEventArgs e)
    {
        for (int f = 0; f < ViewModel.Count; f++)
        {
            var item = new KeyValuePair<string, int>($"{f}, New Key", 1);

            ViewModel[f].Add(item);
        }

    }

    private void ButtonModify_Click(object sender, RoutedEventArgs e)
    {
        for (int f = 0; f < ViewModel.Count; f++)
        {
            for (int j = 0; j < ViewModel[f].Count; j++)
            {
                ViewModel[f][j] = new KeyValuePair<string, int>($"{f}, Modify key", 1);
            }
        }

    }
}

public class DifferenceConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        // Get first and second column ItemsSource
        var firstColumnItemsSource = (List<KeyValuePair<string, int>>)values[0];
        var secondColumnItemsSource = (List<KeyValuePair<string, int>>)values[1];

        // Get second  column current KeyValuePair
        var secondKeyValuePair = (KeyValuePair<string, int>)values[2];

        // Get second keyvaluePair index of second column ItemsSource
        int index = secondColumnItemsSource.IndexOf(secondKeyValuePair);

        // Get two column value
        int firstValue = firstColumnItemsSource[index].Value;
        int secondValue = secondKeyValuePair.Value;

        // Get difference value
        var diff = secondValue - firstValue;

        if (diff < 0)
        {
            return "<";
        }
        else if (diff > 0)
        {
            return ">";
        }
        else
        {
            return "none";
        }
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Output