【问题标题】:MVVM pattern for WPF - 2d graph without using any toolkitsWPF 的 MVVM 模式 - 不使用任何工具包的 2d 图
【发布时间】:2011-06-30 10:52:28
【问题描述】:

需要以最简单的方式(我认为是折线)在 WPF 中使用 MVVM 模式来绘制 2D 图形。我创建了几个类:

    namespace SomeNamespace.Models
    {
        class Info
        {
          //  public  Queue<int> Dots { get; set; }???


            public int Point { get; set; }
            public int GetLoad()
            {
                return new Random (100); //Get some data from external class
            }
        }
    }

    namespace SomeNamespace.ViewModels
        {
public abstract class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    }
            class InfoViewModel: ViewModelBase
            {
              //private Queue<Point> _dots = new Queue<Point>();
            //public Queue<int> Dots
            //{
            //    get { return _dots; }
            //    set
            //    {
            //        _dots = value;
            //        OnPropertyChanged("Dots");
            //    }
            //}

            private int _point;
            public int Point
            {
                get { return _point; }
                set
                {
                    _point = value;
                    OnPropertyChanged("Point");
                }
            }
          }


class MainViewModel : ViewModelBase
    {
       // public ObservableCollection<InfoViewModel> InfoList { get; set; }??
        public ObservableCollection<int> Points { get; set; } 

        public MainViewModel(List<Info>  info)
        {
            //InfoList  = new ObservableCollection<InfoListViewModel>(info.Select i => new InfoViewModel( i)));???
            Points = new ObservableCollection<int>() { 10, 20, 30, 40 }; //just for test
        }



    }
}

在 App.xaml 中

 public partial class App : Application
    {
        private void OnStartup(object sender, StartupEventArgs e)
        {
            List<Info>  i = new List<Info>()
            {
                new Info(){ Point = 10 },
                new Info(){ Point = 15 },
                new Info(){ Point = 20 },


                new Info(){ Point = 25 },
                new Info(){ Point = 30  },
                new Info(){ Point = 35  } 

            };



            MainWindow mainView = new MainWindow();
            MainViewModel mainViewModel = new MainViewModel( i);
            mainView.DataContext = mainViewModel;
            mainView.Show();
        }
    }

在 MainWindow.xaml 中

<Grid>
    <Polyline Name="graph1"   Fill="Blue"
              Points="{Binding Points}"  Stroke="Blue" >

    </Polyline>

 </Grid>

但它不起作用。

编辑:

我写了下面的代码,但是看不懂:

1) 我如何绑定 &lt;Line X1="{Binding ??}" Y1="{Binding ??}" X2="{Binding ??}" Y2="{Binding ??}" Stroke="Red"/&gt; 到队列 ?

2)&lt; Line .../&gt;如何每秒刷新一次?或者 ViewModel 如何每秒刷新一次并通知 View?

public class Segment
    {
        public Queue<Point> Dots { get; set; }

    }

    public class ViewModel:INotifyPropertyChanged
    {
        private Queue<Segment> _segments;
        public Queue<Segment> Segments
        {
            get { return _segments; }
            set
            {
                _segments = value;
                OnPropertyChanged("Segments");
            }
        }


        public ViewModel(Queue<Point> segments)
        {

        }


        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }




 MainWindow mainView = new MainWindow();

            Queue<Point> q = Class1.GenerateData(); //Class1.GenerateData() returns Queue<Point>  
            mainView.DataContext = new ViewModel(q);

【问题讨论】:

    标签: c# wpf xaml data-binding mvvm


    【解决方案1】:

    使用 MVVM 模式在 WPF 中创建穷人图表的最简单方法是将数据转换为易于通过标记使用的格式,特别是段而不是点。

    这里是代表视图模型的代码:

        public class Segment
        {
            public Point From { get; set; }
            public Point To { get; set; }
        }
    
        public class ViewModel
        {
            public IList<Segment> Segments { get; set; }
        }
    
        void SetDataContext()
        {
            var Points = new Point[]
            {
                new Point { X = 0, Y = 10 },
                new Point { X = 10, Y = 30 },
                new Point { X = 20, Y = 20 },
            };
            DataContext = new ViewModel
            {
                Segments = new List<Segment>(Points.Zip(Points.Skip(1), (a, b) => new Segment { From = a, To = b }))
            };
        }
    

    下面是如何从这些数据创建一个简单的图表:

    <Grid>
        <Border Height="100" Width="100" BorderBrush="Black" BorderThickness="1">
            <Canvas Background="Pink">
                <Canvas.LayoutTransform>
                    <ScaleTransform ScaleY="-1"/>
                </Canvas.LayoutTransform>
                <ItemsControl ItemsSource="{Binding Segments}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <Canvas/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Line X1="{Binding From.X}" Y1="{Binding From.Y}" X2="{Binding To.X}" Y2="{Binding To.Y}" Stroke="Red"/>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </Canvas>
        </Border>
    </Grid>
    

    这导致了这个“图表”:

    【讨论】:

    • 看起来像我要找的东西!
    • 是的。这很好。但我还需要每秒刷新一次图表来模拟 CPU 负载。可能我必须实现接口 INotifyPropertyChanged 并使用 Queue.
    • 是的,标准 MVVM 实践适用。在这种情况下,您只需要让ViewModel 专门为Segments 实现INotifyPropertyChanged
    猜你喜欢
    • 2010-11-11
    • 2010-12-17
    • 1970-01-01
    • 2014-05-12
    • 1970-01-01
    • 1970-01-01
    • 2011-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多