Слишком много циклов в приложении рисования

У меня есть метод, который имеет много циклов:

private void update(double depth)
        {

            Console.WriteLine("update with level " + depth);

            this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate()
                {


            List<Grid> grids = new List<Grid>();

            Dependencies.Children.Clear();

            Grid g = new Grid();
            //Canvas.SetZIndex(g, 100);
            g.Width = 50;
            g.Height = 50;
            g.Tag = focus;

            Ellipse e = new Ellipse();
            e.Width = 50;
            e.Height = 50;
            e.Fill = Brushes.Red;
            if (depth == 1)
            {
                Canvas.SetTop(g, 163);
            }
            else if (depth == 2)
            {
                Canvas.SetTop(g, 108);
            }
            else if (depth == 3)
            {
                Canvas.SetTop(g, 81);
            }
            else if (depth == 4)
            {
                Canvas.SetTop(g, 65);
            }
            else if (depth == 5)
            {
                Canvas.SetTop(g, 54);
            }
            else if (depth == 6)
            {
                Canvas.SetTop(g, 46);
            }
            Canvas.SetLeft(g, 500);

            g.Children.Add(e);

            Viewbox box = new Viewbox();
            box.Width = e.Width;
            box.Height = e.Height;


            TextBox txt = new TextBox();
            txt.Text = focus.getName();
            box.Child = txt;
            txt.Background = Brushes.Transparent;
            txt.BorderBrush = Brushes.Transparent;

            g.Children.Add(box);



            grids.Add(g);

            List<SourceFile> list = new List<SourceFile>();

            list = focus.getInvocations();

            int counter = 1;
            foreach (SourceFile sf in list)
            {
                Grid g1 = new Grid();
                //Canvas.SetZIndex(g, 101);
                g1.Width = 50;
                g1.Height = 50;
                g1.Tag = sf;

                Ellipse e1 = new Ellipse();
                //Dependencies.Children.Add(e1);
                sf.setGrid(g1);
                e1.Width = 50;
                e1.Height = 50;
                e1.Fill = Brushes.Red;

                g1.Children.Add(e1);

                if (depth == 1)
                {
                    Canvas.SetTop(g1, 488);
                }
                else if (depth == 2)
                {
                    Canvas.SetTop(g1, 324);
                }
                else if (depth == 3)
                {
                    Canvas.SetTop(g1, 244);
                }
                else if (depth == 4)
                {
                    Canvas.SetTop(g1, 195);
                }
                else if (depth == 5)
                {
                    Canvas.SetTop(g1, 163);
                }
                else if (depth == 6)
                {
                    Canvas.SetTop(g1, 139);
                }
                Canvas.SetLeft(g1, counter * (1000 / (list.Count + 1) ));

                Viewbox box1 = new Viewbox();
                box1.Width = g1.Width;
                box1.Height = g1.Height;

                TextBox txt1 = new TextBox();
                txt1.Text = sf.getName();
                txt1.Background = Brushes.Transparent;
                txt1.BorderBrush = Brushes.Transparent;

                box1.Child = txt1;
                g1.Children.Add(box1);

                Line l = new Line();
                //Canvas.SetZIndex(l, 1);
                l.Stroke = Brushes.Green;
                l.StrokeThickness = 10;
                Binding x1 = new Binding(); x1.Path = new PropertyPath(Canvas.LeftProperty);
                x1.Converter = new MyConverter();
                x1.ConverterParameter = g;
                Binding y1 = new Binding(); y1.Path = new PropertyPath(Canvas.TopProperty);
                y1.Converter = new MyConverter();
                y1.ConverterParameter = g;
                Binding x2 = new Binding(); x2.Path = new PropertyPath(Canvas.LeftProperty);
                x2.Converter = new MyConverter();
                x2.ConverterParameter = g1;
                Binding y2 = new Binding(); y2.Path = new PropertyPath(Canvas.TopProperty);
                y2.Converter = new MyConverter();
                y2.ConverterParameter = g1;
                x1.Source = y1.Source = g;
                x2.Source = y2.Source = g1;
                l.SetBinding(Line.X1Property, x1);
                l.SetBinding(Line.Y1Property, y1);
                l.SetBinding(Line.X2Property, x2);
                l.SetBinding(Line.Y2Property, y2);
                Dependencies.Children.Add(l);
                l.Tag = new Call(focus, sf);
                Contacts.AddPreviewContactDownHandler(l, OnLineDown);
                counter++;

                grids.Add(g1);

                SizeChangedEventHandler act = (Object s, SizeChangedEventArgs args) =>
                {
                    BindingOperations.GetBindingExpressionBase(l, Line.X1Property).UpdateTarget();
                    BindingOperations.GetBindingExpressionBase(l, Line.Y1Property).UpdateTarget();
                    BindingOperations.GetBindingExpressionBase(l, Line.X2Property).UpdateTarget();
                    BindingOperations.GetBindingExpressionBase(l, Line.Y2Property).UpdateTarget();
                };

                g.SizeChanged += act;
                g1.SizeChanged += act;
            }


            int counter2 = 1;
            if (depth >= 2)
            {

                int invocCount = 0;

                foreach (SourceFile s in list)
                {
                    foreach (SourceFile source in s.getInvocations())
                    {
                        invocCount = invocCount + s.getInvocations().Count;
                    }
                }

                Console.WriteLine(invocCount);

                foreach (SourceFile s in list)
                {
                    foreach (SourceFile source in s.getInvocations())
                    {

                        Console.WriteLine("`Found invocation of " + s.getName() + ": " + source.getName());

                        Grid g1 = new Grid();
                        g1.Width = 50;
                        g1.Height = 50;

                        Ellipse e1 = new Ellipse();
                       // Canvas.SetZIndex(g1, 102);
                        grids.Add(g1);
                        e1.Width = 50;
                        e1.Height = 50;
                        e1.Fill = Brushes.Red;
                        source.setGrid(g1);
                        g1.Tag = source;

                        g1.Children.Add(e1);

                        if (depth == 2)
                        {
                            Canvas.SetTop(g1, 540);
                        }
                        else if (depth == 3)
                        {
                            Canvas.SetTop(g1, 406);
                        }
                        else if (depth == 4)
                        {
                            Canvas.SetTop(g1, 325);
                        }
                        else if (depth == 5)
                        {
                            Canvas.SetTop(g1, 271);
                        }
                        else if (depth == 6)
                        {
                            Canvas.SetTop(g1, 232);
                        }

                        Canvas.SetLeft(g1, counter2 * (1000 / (invocCount + 1)));

                        Viewbox box1 = new Viewbox();
                        box1.Width = g1.Width;
                        box1.Height = g1.Height;

                        TextBox txt1 = new TextBox();
                        txt1.Text = source.getName();
                        txt1.Background = Brushes.Transparent;
                        txt1.BorderBrush = Brushes.Transparent;

                        box1.Child = txt1;
                        g1.Children.Add(box1);

                        Line l = new Line();
                        //Canvas.SetZIndex(l, 2);
                        l.Stroke = Brushes.Green;
                        l.StrokeThickness = 10;
                        Binding x1 = new Binding(); x1.Path = new PropertyPath(Canvas.LeftProperty);
                        x1.Converter = new MyConverter();
                        x1.ConverterParameter = s.getGrid();
                        Binding y1 = new Binding(); y1.Path = new PropertyPath(Canvas.TopProperty);
                        y1.Converter = new MyConverter();
                        y1.ConverterParameter = s.getGrid();
                        Binding x2 = new Binding(); x2.Path = new PropertyPath(Canvas.LeftProperty);
                        x2.Converter = new MyConverter();
                        x2.ConverterParameter = g1;
                        Binding y2 = new Binding(); y2.Path = new PropertyPath(Canvas.TopProperty);
                        y2.Converter = new MyConverter();
                        y2.ConverterParameter = g1;
                        x1.Source = y1.Source = findGrid(grids, s, source);
                        x2.Source = y2.Source = g1;
                        l.SetBinding(Line.X1Property, x1);
                        l.SetBinding(Line.Y1Property, y1);
                        l.SetBinding(Line.X2Property, x2);
                        l.SetBinding(Line.Y2Property, y2);
                        Dependencies.Children.Add(l);
                        l.Tag = new Call(s, source);
                        Contacts.AddPreviewContactDownHandler(l, OnLineDown);

                        counter2++;

                        SizeChangedEventHandler act = (Object o, SizeChangedEventArgs args) =>
                        {
                            BindingOperations.GetBindingExpressionBase(l, Line.X1Property).UpdateTarget();
                            BindingOperations.GetBindingExpressionBase(l, Line.Y1Property).UpdateTarget();
                            BindingOperations.GetBindingExpressionBase(l, Line.X2Property).UpdateTarget();
                            BindingOperations.GetBindingExpressionBase(l, Line.Y2Property).UpdateTarget();
                        };

                        source.getGrid().SizeChanged += act;
                        g1.SizeChanged += act;
                    }
                }
            }


            int counter3 = 1;
            if (depth >= 3)
            {

                int invocCount = 0;

                foreach (SourceFile s in list)
                {
                    foreach (SourceFile source in s.getInvocations())
                    {
                        foreach (SourceFile s1 in source.getInvocations())
                        {
                            invocCount = invocCount + source.getInvocations().Count;
                        }
                    }
                }

                foreach (SourceFile s in list)
                {
                    foreach (SourceFile source in s.getInvocations())
                    {
                        foreach (SourceFile s1 in source.getInvocations())
                        {
                            Grid g1 = new Grid();
                            grids.Add(g1);
                            g1.Width = 50;
                            g1.Height = 50;
                            g1.Tag = s1;
                            Ellipse e1 = new Ellipse();

                            e1.Width = 50;
                            e1.Height = 50;
                            e1.Fill = Brushes.Red;
                            s1.setGrid(g1);
                            g1.Children.Add(e1);

                            if (depth == 3)
                            {
                                Canvas.SetTop(g1, 569);
                            }
                            else if (depth == 4)
                            {
                                Canvas.SetTop(g1, 455);
                            }
                            else if (depth == 5)
                            {
                                Canvas.SetTop(g1, 379);
                            }
                            else if (depth == 6)
                            {
                                Canvas.SetTop(g1, 325);
                            }
                            Canvas.SetLeft(g1, counter3 * (1000 / (invocCount + 1)));

                            Viewbox box1 = new Viewbox();
                            box1.Width = g1.Width;
                            box1.Height = g1.Height;

                            TextBox txt1 = new TextBox();
                            txt1.Background = Brushes.Transparent;
                            txt1.BorderBrush = Brushes.Transparent;
                            txt1.Text = s1.getName();
                            box1.Child = txt1;
                            g1.Children.Add(box1);

                            Line l = new Line();
                            //Canvas.SetZIndex(l, 2);
                            l.Stroke = Brushes.Green;
                            l.StrokeThickness = 10;
                            Binding x1 = new Binding(); x1.Path = new PropertyPath(Canvas.LeftProperty);
                            x1.Converter = new MyConverter();
                            x1.ConverterParameter = source.getGrid();
                            Binding y1 = new Binding(); y1.Path = new PropertyPath(Canvas.TopProperty);
                            y1.Converter = new MyConverter();
                            y1.ConverterParameter = source.getGrid();
                            Binding x2 = new Binding(); x2.Path = new PropertyPath(Canvas.LeftProperty);
                            x2.Converter = new MyConverter();
                            x2.ConverterParameter = g1;
                            Binding y2 = new Binding(); y2.Path = new PropertyPath(Canvas.TopProperty);
                            y2.Converter = new MyConverter();
                            y2.ConverterParameter = g1;
                            x1.Source = y1.Source = findGrid(grids, source, s1);
                            x2.Source = y2.Source = g1;
                            l.SetBinding(Line.X1Property, x1);
                            l.SetBinding(Line.Y1Property, y1);
                            l.SetBinding(Line.X2Property, x2);
                            l.SetBinding(Line.Y2Property, y2);
                            Dependencies.Children.Add(l);
                            l.Tag = new Call(source, s1);
                            Contacts.AddPreviewContactDownHandler(l, OnLineDown);

                            counter3++;

                            SizeChangedEventHandler act = (Object o, SizeChangedEventArgs args) =>
                            {
                                BindingOperations.GetBindingExpressionBase(l, Line.X1Property).UpdateTarget();
                                BindingOperations.GetBindingExpressionBase(l, Line.Y1Property).UpdateTarget();
                                BindingOperations.GetBindingExpressionBase(l, Line.X2Property).UpdateTarget();
                                BindingOperations.GetBindingExpressionBase(l, Line.Y2Property).UpdateTarget();
                            };

                            s1.getGrid().SizeChanged += act;
                            g1.SizeChanged += act;
                        }
                    }
                }
            }


         int counter4 = 1;
         if (depth >= 4)
         {

             int invoCount = 0;
             foreach (SourceFile s in list)
             {
                 foreach (SourceFile source in s.getInvocations())
                 {
                     foreach (SourceFile s1 in source.getInvocations())
                     {
                         foreach (SourceFile s2 in s1.getInvocations())
                         {
                             invoCount = invoCount + s1.getInvocations().Count;
                         }
                     }
                 }
             }

             foreach (SourceFile s in list)
             {
                 foreach (SourceFile source in s.getInvocations())
                 {
                     foreach (SourceFile s1 in source.getInvocations())
                     {
                         foreach (SourceFile s2 in s1.getInvocations())
                         {

                             Grid g1 = new Grid();
                             grids.Add(g1);
                             g1.Width = 50;
                             g1.Height = 50;
                             g1.Tag = s2;
                             Ellipse e1 = new Ellipse();

                             e1.Width = 50;
                             e1.Height = 50;
                             e1.Fill = Brushes.Red;
                             s2.setGrid(g1);

                             g1.Children.Add(e1);

                             if (depth == 4)
                             {
                                 Canvas.SetTop(g1, 585);
                             }
                             else if (depth == 5)
                             {
                                 Canvas.SetTop(g1, 488);
                             }
                             else if (depth == 6)
                             {
                                 Canvas.SetTop(g1, 418);
                             }
                             Canvas.SetLeft(g1, counter4 * (1000 / (invoCount + 1)));

                             Viewbox box1 = new Viewbox();
                             box1.Width = g1.Width;
                             box1.Height = g1.Height;

                             TextBox txt1 = new TextBox();
                             txt1.Background = Brushes.Transparent;
                             txt1.BorderBrush = Brushes.Transparent;
                             txt1.Text = s2.getName();
                             box1.Child = txt1;
                             g1.Children.Add(box1);

                             Line l = new Line();
                             //Canvas.SetZIndex(l, 2);
                             l.Stroke = Brushes.Green;
                             l.StrokeThickness = 10;
                             Binding x1 = new Binding(); x1.Path = new PropertyPath(Canvas.LeftProperty);
                             x1.Converter = new MyConverter();
                             x1.ConverterParameter = s1.getGrid();
                             Binding y1 = new Binding(); y1.Path = new PropertyPath(Canvas.TopProperty);
                             y1.Converter = new MyConverter();
                             y1.ConverterParameter = s1.getGrid();
                             Binding x2 = new Binding(); x2.Path = new PropertyPath(Canvas.LeftProperty);
                             x2.Converter = new MyConverter();
                             x2.ConverterParameter = g1;
                             Binding y2 = new Binding(); y2.Path = new PropertyPath(Canvas.TopProperty);
                             y2.Converter = new MyConverter();
                             y2.ConverterParameter = g1;
                             x1.Source = y1.Source = findGrid(grids, s1, s2);
                             x2.Source = y2.Source = g1;
                             l.SetBinding(Line.X1Property, x1);
                             l.SetBinding(Line.Y1Property, y1);
                             l.SetBinding(Line.X2Property, x2);
                             l.SetBinding(Line.Y2Property, y2);
                             Dependencies.Children.Add(l);
                             l.Tag = new Call(s1, s2);
                             Contacts.AddPreviewContactDownHandler(l, OnLineDown);
                             counter4++;

                             SizeChangedEventHandler act = (Object o, SizeChangedEventArgs args) =>
                             {
                                 BindingOperations.GetBindingExpressionBase(l, Line.X1Property).UpdateTarget();
                                 BindingOperations.GetBindingExpressionBase(l, Line.Y1Property).UpdateTarget();
                                 BindingOperations.GetBindingExpressionBase(l, Line.X2Property).UpdateTarget();
                                 BindingOperations.GetBindingExpressionBase(l, Line.Y2Property).UpdateTarget();
                             };

                             s2.getGrid().SizeChanged += act;
                             g1.SizeChanged += act;
                         }
                     }
                 }
             }
         }



      int counter5 = 1;
      if (depth >= 5)
      {

          int invoCount = 0;

          foreach (SourceFile s in list)
          {
              foreach (SourceFile source in s.getInvocations())
              {
                  foreach (SourceFile s1 in source.getInvocations())
                  {
                      foreach (SourceFile s2 in s1.getInvocations())
                      {
                          foreach (SourceFile s3 in s2.getInvocations())
                          {
                              invoCount = invoCount + s2.getInvocations().Count;
                          }
                      }
                  }
              }
          }

          foreach (SourceFile s in list)
          {
              foreach (SourceFile source in s.getInvocations())
              {
                  foreach (SourceFile s1 in source.getInvocations())
                  {
                      foreach (SourceFile s2 in s1.getInvocations())
                      {
                          foreach (SourceFile s3 in s2.getInvocations())
                          {
                              Grid g1 = new Grid();
                              g1.Width = 50;
                              g1.Height = 50;
                              grids.Add(g1);
                              g1.Tag = s3;
                              Ellipse e1 = new Ellipse();
                              //Dependencies.Children.Add(e1);
                              e1.Width = 50;
                              e1.Height = 50;
                              e1.Fill = Brushes.Red;
                              s3.setGrid(g1);

                              g1.Children.Add(e1);

                              if (depth == 5)
                              {
                                  Canvas.SetTop(g1, 596);
                              }
                              else if (depth == 6)
                              {
                                  Canvas.SetTop(g1, 511);
                              }
                              Canvas.SetLeft(g1, counter5 * (1000 / (invoCount + 1)));

                              Viewbox box1 = new Viewbox();
                              box1.Width = g1.Width;
                              box1.Height = g1.Height;

                              TextBox txt1 = new TextBox();
                              txt1.Background = Brushes.Transparent;
                              txt1.BorderBrush = Brushes.Transparent;
                              txt1.Text = s3.getName();
                              box1.Child = txt1;
                              g1.Children.Add(box1);

                              Line l = new Line();
                              //Canvas.SetZIndex(l, 2);
                              l.Stroke = Brushes.Green;
                              l.StrokeThickness = 10;
                              Binding x1 = new Binding(); x1.Path = new PropertyPath(Canvas.LeftProperty);
                              x1.Converter = new MyConverter();
                              x1.ConverterParameter = s2.getGrid();
                              Binding y1 = new Binding(); y1.Path = new PropertyPath(Canvas.TopProperty);
                              y1.Converter = new MyConverter();
                              y1.ConverterParameter = s2.getGrid();
                              Binding x2 = new Binding(); x2.Path = new PropertyPath(Canvas.LeftProperty);
                              x2.Converter = new MyConverter();
                              x2.ConverterParameter = g1;
                              Binding y2 = new Binding(); y2.Path = new PropertyPath(Canvas.TopProperty);
                              y2.Converter = new MyConverter();
                              y2.ConverterParameter = g1;
                              x1.Source = y1.Source = findGrid(grids, s2, s3);
                              x2.Source = y2.Source = g1;
                              l.SetBinding(Line.X1Property, x1);
                              l.SetBinding(Line.Y1Property, y1);
                              l.SetBinding(Line.X2Property, x2);
                              l.SetBinding(Line.Y2Property, y2);
                              l.Tag = new Call(s2, s3);
                              Contacts.AddPreviewContactDownHandler(l, OnLineDown);
                              Dependencies.Children.Add(l);

                              counter5++;

                              SizeChangedEventHandler act = (Object o, SizeChangedEventArgs args) =>
                              {
                                  BindingOperations.GetBindingExpressionBase(l, Line.X1Property).UpdateTarget();
                                  BindingOperations.GetBindingExpressionBase(l, Line.Y1Property).UpdateTarget();
                                  BindingOperations.GetBindingExpressionBase(l, Line.X2Property).UpdateTarget();
                                  BindingOperations.GetBindingExpressionBase(l, Line.Y2Property).UpdateTarget();
                              };

                              s3.getGrid().SizeChanged += act;
                              g1.SizeChanged += act;
                          }
                      }
                  }
              }
          }
      }



            foreach (Grid grid in grids)
            {
                Dependencies.Children.Add(grid);
                Contacts.AddPreviewContactDownHandler(grid, DownOnSourceFile);
            }
                }
  ));
        }

Есть ли простой способ улучшить это? И чтобы он работал не только на 6 шагов, но и на n шагов?

31 голос | спросил RoflcoptrException 20 Jam1000000amThu, 20 Jan 2011 00:19:59 +030011 2011, 00:19:59

11 ответов


61

Разбейте это на несколько методов - это очень длинный, что означает, что читать его непросто.

ответил LRE 20 Jam1000000amThu, 20 Jan 2011 00:24:59 +030011 2011, 00:24:59
59

Этот код ...

if (depth == 1)
{
    Canvas.SetTop(g1, 163);
}
else if (depth == 2)
{
    Canvas.SetTop(g1, 108);
}
else if (depth == 3)
{
    Canvas.SetTop(g1, 81);
}
else if (depth == 4)
{
    Canvas.SetTop(g1, 65);
}
else if (depth == 5)
{
    Canvas.SetTop(g1, 54);
}
else if (depth == 6)
{
    Canvas.SetTop(g1, 46);
}

Может быть лучше реализовано с использованием массива ...

int[] values = new [] { 0, 163, 108, 81, 65, 54, 46  }

Или словарь ...

var values = new Dictionary<int,int>() { { 1, 163 }, { 2, 108 }, { 3, 81 }, { 4, 65 }, { 5, 54 }, { 6, 46} };

Таким образом, вы могли бы просто сказать

Canvas.SetTop(g1, values[depth])
ответил Carlos Muñoz 20 Jam1000000amThu, 20 Jan 2011 01:34:52 +030011 2011, 01:34:52
28

Есть несколько сразу очевидных вещей, о которых еще не упоминалось:

В коде есть много магических чисел. Постарайтесь определить их как const s со значимыми именами.

Например

g.Width = 50;

становится

private const int DefaultGridWidth = 50;
...
g.Width = DefaultGridWidth;

Похоже на тривиальное изменение, но это имеет большое значение для тех, кто читает ваш код. Он дает указание , почему значение равно 50, а не только 50.


Вы должны использовать более значимые имена для своих идентификаторов. Имена, подобные g и g1, не говорят мне о том, что такое объект, но mainGrid и innerGrid содержат дополнительная информация для читателя.
ответил Nobody 20 Jpm1000000pmThu, 20 Jan 2011 13:33:10 +030011 2011, 13:33:10
17

Подумайте о том, чтобы абстрагировать решения, связанные с установкой верхней части холста (см. все эти операторы if) в набор классов - или, возможно, один класс с различными подходящими параметрами в конструктор. Большая часть этого кода отличается только от применяемых чисел.

Простым правилом является «Абстрактное понятие, которое меняется».

ответил LRE 20 Jam1000000amThu, 20 Jan 2011 00:27:45 +030011 2011, 00:27:45
17

Поскольку вы используете C #, вы можете сделать свои инициализаторы немного приятнее:

Grid g = new Grid()
{
    Width = 50,
    Height = 50,
    Tag = focus,
}
//Canvas.SetZIndex(g, 100);

Последняя часть вашего кода (или, вернее, вторая половина) делает очень похожие вещи несколько раз: дублирование кода - это знак того, что ваш код можно сделать более понятным. Например (обратите внимание, что ваш код почти наверняка содержит ошибку! Инструкция внутри всех циклов вызывает s2, а не s3):

foreach (SourceFile s in list)
{
    foreach (SourceFile source in s.getInvocations())
    {
        foreach (SourceFile s1 in source.getInvocations())
        {
            foreach (SourceFile s2 in s1.getInvocations())
            {
                foreach (SourceFile s3 in s2.getInvocations())
                {
                    invoCount = invoCount + s2.getInvocations().Count;
                }
            }
        }
    }
}

можно изменить на

list.CountRecursive(t => t.getInvocations(), t => t.getInvocations().Count, 5);

(...)

public static int CountRecursive<T>(this IEnumerable<T> x, Func<T, IEnumerable<T>> f, Func<T, int> c, int depth)
{
    int counter = 0;
    foreach (T t in x)
    {
        if (depth > 1)
        {
            counter += f(t).CountRecursive(f, c, depth - 1);
        }
        else
        {
            counter += c(t);
        }
    }
    return counter;
}

, что также значительно облегчает его выполнение для разных уровней рекурсии.

ответил Alex ten Brink 21 Jam1000000amFri, 21 Jan 2011 03:30:18 +030011 2011, 03:30:18
8

Я мог бы рекомендовать использование операторов switch и пробелов вместе с предложением LRE о разрыве этого на несколько методов. Также похоже, что у вас есть довольно много повторного кода, возможно, попытайтесь сломать это, конечно же, своими собственными методами.

ответил percent20 20 Jam1000000amThu, 20 Jan 2011 00:29:43 +030011 2011, 00:29:43
7

Я реорганизовал его для вас. Я сделал все это без тестирования, так что, вероятно, будет множество ошибок и ошибок. Я также сделал некоторые предположения о коде, который вы не включили. Теперь, когда код намного меньше, вам будет легче найти эти ошибки.

Несколько важных моментов:

  1. Рекурсия является фундаментальной концепцией программирования. Если вы профессиональный программист, вам абсолютно необходимо быть с ним комфортно, иначе вы никогда не сможете эффективно работать с вложенными структурами.

  2. Если вы копируете и вставляете, вы делаете это неправильно. Каждый раз, когда вы нажимаете Ctrl + C, умирает котенок. Нет, нет.

  3. Если у вас есть переменные с именем something1, something2, something3 и т. д. , вы делаете это неправильно . По крайней мере, они должны быть массивом.

  4. У вас был depth как double, но сравнивали его с буквальными значениями, отличными от нуля. Это плохо.

Здесь вы идете:

private void update(int depth)
{
    Console.WriteLine("update with level " + depth);

    Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(delegate()
    {
        List<Grid> grids = new List<Grid>();

        Dependencies.Children.Clear();

        Grid grid = MakeOuterGrid(grids, focus, e.Width, e.Height, depth);

        List<SourceFile> list = focus.getInvocations();

        for (int i = 1; i <= depth; i++)
        {
            int invocCount = CountInvocations(focus, i + 1);
            int counter = 0;
            MakeRecursiveGrids(grids, null, focus, i, invocCount, i, ref counter);
        }

        foreach (Grid grid in grids)
        {
            Dependencies.Children.Add(grid);
            Contacts.AddPreviewContactDownHandler(grid, DownOnSourceFile);
        }
    }));
}

void AdjustTop(int depth, int table) {
    int[][] depthTable = new int[][] {
        new int[] { 163, 108,  81,  65,  54,  46 },
        new int[] { 488, 324, 244, 195, 163, 139 },
        new int[] {  -1, 540, 406, 325, 271, 232 },
        new int[] {  -1,  -1, 569, 455, 379, 325 },
        new int[] {  -1,  -1,  -1, 585, 488, 418 },
        new int[] {  -1,  -1,  -1,  -1, 596, 511 },
    }

    int[] depths = depthTable[table];
    if ((depth < depths.Length) && (depths[depth - 1] != -1)) {
        Canvas.SetTop(depths[depth - 1]);
    }
}

SizeChangedEventHandler UpdateBindings(Line line) {
    SizeChangedEventHandler act = (Object o, SizeChangedEventArgs args) =>
    {
        BindingOperations.GetBindingExpressionBase(line, Line.X1Property).UpdateTarget();
        BindingOperations.GetBindingExpressionBase(line, Line.Y1Property).UpdateTarget();
        BindingOperations.GetBindingExpressionBase(line, Line.X2Property).UpdateTarget();
        BindingOperations.GetBindingExpressionBase(line, Line.Y2Property).UpdateTarget();
    };

    return act;
}

int CountInvocations(SourceFile source, int depth)
{
    int count = 0;

    if (depth > 0)
    {
        foreach (SourceFile inner in source.getInvocations())
        {
            count = count + CountInvocations(inner, depth - 1);
        }
    }
    else
    {
        count = source.Count;
    }

    return count;
}

Grid MakeGrid(List<Grid> grids, SourceFile source)
{
    Grid grid = new Grid();
    grid.Width = 50;
    grid.Height = 50;
    grid.Tag = source;
    source.setGrid(grid);
    grids.Add(grid);

    Ellipse ellipse = new Ellipse();
    ellipse.Width = 50;
    ellipse.Height = 50;
    ellipse.Fill = Brushes.Red;

    grid.Children.Add(ellipse);

    return grids;
}

void MakeRecursiveGrids(List<Grid> grids, SourceFile outer, SourceFile source,
    int maxDepth, int invocCount, int recurseDepth, ref int counter)
{
    if (recurseDepth > 0)
    {
        foreach (SourceFile inner in source)
        {
            MakeRecursiveGrids(grids, source, inner, maxDepth, invocCount,
                recurseDepth - 1, ref counter);
        }
    }
    else
    {
        MakeGrid(grids, outer, inner, depth, maxDepth, invocCount, counter);
        counter++;
    }
}

Grid MakeGrid(List<Grid> grids, SourceFile outer, SourceFile inner,
    int depth, int[] depths, int invocCount, int counter)
{
    Grid grid = MakeGrid(grids, inner);

    MakeViewbox(grid, grid.Width, grid.Height, inner.getName());

    AdjustTop(depth, depths);
    Canvas.SetLeft(grid, counter * (1000 / (invocCount + 1)));

    MakeLine(grids, grid, outer, inner);

    return grid;
}

Grid MakeOuterGrid(List<Grid> grids, SourceFile inner, int width, int height,
    int depth)
{
    Grid grid = MakeGrid(grids, inner);

    MakeViewbox(grid, width, height, inner.getName());

    AdjustTop(depth, 0);
    Canvas.SetLeft(grid, 500);

    return grid;
}

Binding MakeBinding(Object parameter, Grid grid)
{
    Binding binding = new Binding();
    binding.Path = new PropertyPath(parameter);
    binding.Converter = new MyConverter();
    binding.ConverterParameter = grid;
}

void MakeLine(List<Grid> grids, Grid grid, SourceFile outer, SourceFile inner)
{
    Grid g2 = outer.getGrid();

    Line line = new Line();
    line.Stroke = Brushes.Green;
    line.StrokeThickness = 10;

    Binding x1 = MakeBinding(Canvas.LeftProperty, g2);
    Binding y1 = MakeBinding(Canvas.TopProperty, g2);
    Binding x2 = MakeBinding(Canvas.LeftProperty, grid);
    Binding y2 = MakeBinding(Canvas.TopProperty, grid);

    Grid g = findGrid(grids, outer, inner);
    x1.Source = g;
    y1.Source = g;
    x2.Source = grid;
    y2.Source = grid;

    line.SetBinding(Line.X1Property, x1);
    line.SetBinding(Line.Y1Property, y1);
    line.SetBinding(Line.X2Property, x2);
    line.SetBinding(Line.Y2Property, y2);

    Dependencies.Children.Add(line);

    Contacts.AddPreviewContactDownHandler(line, OnLineDown);

    line.Tag = new Call(outer, inner);

    SizeChangedEventHandler act = UpdateBindings(line);
    inner.getGrid().SizeChanged += act;
    g1.SizeChanged += act;
}

void MakeViewBox(Grid grid, int width, int height, string text)
{
    Viewbox box = new Viewbox();
    box.Width = width;
    box.Height = height;

    TextBox textBox = new TextBox();
    textBox.Text = text;

    box.Child = textBox;

    grid.Children.Add(box);
}
ответил munificent 27 Jpm1000000pmThu, 27 Jan 2011 22:12:58 +030011 2011, 22:12:58
6

Это должно упростить цикл, предполагая, что вы можете обобщить код позиционирования, как упоминание в нескольких других ответах

        //Get the initial set of sourcefiles
        var sourceFiles = from file in list
              from invocation in file.getInvocations()
              group invocation by (SourceFile)null into groupedByInvoker
              select groupedByInvoker;

        for (var currentDepth = 0; currentDepth <= depth; currentDepth++)
        {
            foreach (var currentGroup in sourceFiles)
            {
                int sourceFileCount = currentGroup.Count();
                int counter = 0;

                foreach (var invocation in currentGroup)
                {
                    /*
                     * Generalized grid code goes here
                     */
                    counter++;
                }
            }

            //Select the current sub source files
         sourceFiles = from invokerGroup in sourceFiles
              from file in invokerGroup
              from invocation in file.getInvocations()
              group invocation by file into groupedByInvoker
              select groupedByInvoker;

        }

Это не точное сопоставление с указанным выше кодом, так как сначала он пересекает ширину дерева getInvocations, а не глубину.

Обновлено с помощью imput из Обновить сетку из исходной иерархии

ответил Sean Lynch 21 Jam1000000amFri, 21 Jan 2011 00:43:51 +030011 2011, 00:43:51
5

Для бит n шагов рассмотрите возможность использования рекурсии - но осторожно протестируйте.

ответил LRE 20 Jam1000000amThu, 20 Jan 2011 00:29:04 +030011 2011, 00:29:04
3

Разделите свой код на свои собственные методы определенно, есть и другие способы, но это, вероятно, будет самым простым и менее трудоемким способом упростить чтение и отладку трека для начала.

ответил Dwayne Charrington 20 Jam1000000amThu, 20 Jan 2011 03:18:27 +030011 2011, 03:18:27
3

Вместо Grid g и Ellipse e используйте Grid grid и Ellipse ellipse. Локаль с e.size= говорит меньше ellipse.Size=.

ответил Ruudjah 27 Jpm1000000pmThu, 27 Jan 2011 22:44:05 +030011 2011, 22:44:05

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132