Is it possible to place an item infront of other in FrameworkElement

Emon Haque 3,176 Reputation points
2021-06-02T03:34:59.87+00:00

I, first, created this BarChart with Canvas, then with Panel and with both of those I used ZIndex to bring those bars (Border) infront of Lines. Now it's FrameworkElement and since I add those borders before lines in the VisualCollection of FrameworkElement they're placed behind the lines:

101518-test.gif

there's no SetZIndex in FrameworkElement. Is there any other method or property which I can use to place items in the order I want?

Developer technologies | Windows Presentation Foundation
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. DaisyTian-1203 11,646 Reputation points
    2021-06-03T05:55:45.767+00:00

    You could try to add below ZIndex property for a custom FrameworkElement:

    public int ZIndex  
            {  
                get  
                {  
                    return Canvas.GetZIndex(this);  
                }  
                set  
                {  
                    Canvas.SetZIndex(this, value);  
                }  
            }  
    

    Then assign int value to ZIndex when you create it.


    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

  2. Emon Haque 3,176 Reputation points
    2021-06-03T06:41:30.277+00:00

    I've created a Zline class like this:

    class ZLine : FrameworkElement  
    {  
        Line line;  
        public double X1 { get => line.X1; set => line.X1 = value; }  
        public double X2 { get => line.X2; set => line.X2 = value; }  
        public double Y1 { get => line.Y1; set => line.Y1 = value; }  
        public double Y2 { get => line.Y2; set => line.Y2 = value; }  
        public Brush Stroke { get => line.Stroke; set => line.Stroke = value; }  
        public double StrokeThickness { get => line.StrokeThickness; set => line.StrokeThickness = value; }  
        public int ZIndex { get => Canvas.GetZIndex(this); set => Canvas.SetZIndex(this, value); }  
    
        public ZLine() {  
            line = new Line();  
            AddVisualChild(line);  
        }  
        protected override Size MeasureOverride(Size availableSize) {  
            line.Measure(availableSize);  
            return line.DesiredSize;  
        }  
        protected override Size ArrangeOverride(Size finalSize) {  
            line.Arrange(new Rect(line.DesiredSize));  
            return finalSize;  
        }  
        protected override Visual GetVisualChild(int index) => line;  
        protected override int VisualChildrenCount => 1;  
    }  
    

    and added this

    public int ZIndex { get => Canvas.GetZIndex(this); set => Canvas.SetZIndex(this, value); }  
    

    property in BarWithBorder class. In the BarChart class in that link, I've modified the addLine method to this:

    void addLine() {  
        var line = new ZLine() {  
            StrokeThickness = 1,  
            Stroke = Brushes.LightBlue,  
            IsHitTestVisible = false  
        };  
        Children.Add(line);  
        line.ZIndex = 1;  
        line.Loaded += animateLines;  
    }  
    

    and modified the onSourceChanged to set ZIndex of BarWithBorder like this:

     static void onSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {  
         var o = d as Barchart;  
         if (e.OldValue != null) o.Children.Clear();  
         o.labelDesired = new Size(0, 0);  
         o.maxValue = 0;  
         var list = (IEnumerable<int>)e.NewValue;  
         foreach (int value in list) {  
             if(o.IsWithRect) o.Children.Add(new BarWithRect(value));  
             else {  
                 var bar = new BarWithBorder(value);  
                 Children.Add(bar);  
                 bar.ZIndex = 2;  
             }  
             o.addLabel(DateTime.Today.ToString("dd MMM yyyy"));  
             if (value > o.maxValue) o.maxValue = value;  
             if (value < o.minValue) o.minValue = value;  
         }  
         var min = o.minValue < 0 ? o.minValue : 0;  
         double step = 0d;  
         var current = min;  
         if (min < 0) step = (o.maxValue + Math.Abs(min)) / 9;  
         else step = o.maxValue / 9;  
         for (int i = 0; i < 10; i++) {  
             o.addLine();  
             o.addTick(current);  
             current += step;  
         }  
     }  
    

    and changed these lines of ArrangeOverride

    else if (item is Line) {  
        var line = item as Line;  
        ....  
    }  
    

    to these:

    else if (item is ZLine) {  
        var line = item as ZLine;  
        ....  
    }  
    

    BUT nothing changed. Bars are still behind the Lines.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.