0
votes

Problem: I have a ListBox with TextBlocks whos Text property are bound to different properties. I wish to drag the TextBlock onto a OxyPlot and have the plot create a new LineSeries with a collection that should be bound to the same binding as for the TextBlock (is this making sense?)

I have derived a class from TextBlock to handle the OnMouseMove event like this:

    protected override void OnMouseMove(MouseEventArgs e)
    {
        base.OnMouseMove(e);
        if (CanDrag && (e.LeftButton == MouseButtonState.Pressed))
        {
            // Make sure we have a data binding
            BindingExpression binding = GetBindingExpression(TextProperty);
            if(binding == null)
            { return; }
            // Package the data.
            DataObject data = new DataObject();
            data.SetData("DragListText.Binding", binding);

            // Inititate the drag-and-drop operation.
            DragDrop.DoDragDrop(this, data, DragDropEffects.Copy);
        }
    }

Also I have derived a class from Oxy.Plot that handles the OnDrop:

protected override void OnDrop(DragEventArgs e)
    {
        base.OnDrop(e);
        // DataObject must contain a DragListText.Binding object
        if (e.Data.GetDataPresent("DragListText.Binding"))
        {
            BindingExpression binding = e.Data.GetData("DragListText.Binding") as BindingExpression;
            AddSeries(binding);
        }
        e.Handled = true;
    }

The AddSeries function does the following:

public void AddSeries(BindingExpression binding)
    {
        plot1 = new PlotCollection();

        LineSeries newSeries = new LineSeries();
        newSeries.ItemsSource = plot1.Collection;

        Series.Add(newSeries);
    }

And lastly the PlotCollection is defined as:

public class PlotCollection : DependencyObject
{
    public ObservableCollection<DataPoint> Collection;

    public static DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double), typeof(PlotCollection), new PropertyMetadata(0.0, new PropertyChangedCallback(OnValueChanged)));

    private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    { ((PlotCollection)d).AddLast(); }

    public double Value
    {
        get { return (double)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    public PlotCollection()
    {
        Collection = new ObservableCollection<DataPoint>();
    }
    protected void AddLast()
    {
        Collection.Add(new DataPoint(OxyPlot.Axes.DateTimeAxis.ToDouble(DateTime.Now), Value));
    }
}

So my question is this: How do I create a binding on PlotCollection.Value that matches the one from the TextBlock.Text?

2
Personally I would try to work with data objects, not UI objects. So rather than dragging a TextBlock, you drag whatever the TextBlock.DataContext object is. Then OnDrop, you have the actual object the TextBlock is binding to, and can parse it however you want into the data item the OxyPlot chart is bound to. For an example of dragging/dropping databound items, I usually point people to Bea Stollnitz's blog post (Sadly it no longer exists, but the wayback machine has a copy of it)Rachel
Hi Rachel, Thanks for your reply. The problem is that I have a lot of data comming from a PLC which i store as properties in a class. It is these properties that I am showing in the listbox (using textblocks) and wish to drag to the plot, not the textblocks themselves. So for example i have the property Plc.HPU_Pressure as a double bound to a textblock and it is this property i want to be shown in the plot.Steen Hansen

2 Answers

0
votes

In your AddSeries method, try adding this line of code:

BindingOperations.SetBinding(plot1, PlotCollection.ValueProperty, binding.ParentBinding);
0
votes

Found out the problem,

I needed to add a PropertyChangedCallback to the ValueProperty declaration, like this:

public static DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double), typeof(DynamicSeries), new PropertyMetadata(0.0, OnValueChanged));

And then handle the property changes in the callback method:

private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        PlotCollection ds = (PlotCollection)d;
        ds.AppendValue((double)e.NewValue);
    }

I guess that I have misunderstood how the Value property works?!

Thanks for taking the time to try and help me...