WPF的MVVM模式 - 不使用任何工具包绘制2D图形

5
需要用最简单的方式(我认为应该是折线)在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)如何将<Line X1="{Binding ??}" Y1="{Binding ??}" X2="{Binding ??}" Y2="{Binding ??}" Stroke="Red"/>绑定到Queue<Point>?

2)如何使< Line .../>每秒刷新一次?或者如何让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);
1个回答

6

使用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<Point>。 - user266003
是的,标准的MVVM实践适用。在这种情况下,您仅需要让ViewModel实现INotifyPropertyChanged接口,特别是针对Segments - Rick Sladkey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接