WPF 的 MVVM 模式 - 不使用任何工具包的二维图

发布于 2024-10-17 23:31:27 字数 4431 浏览 1 评论 0原文

需要在 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)如何绑定 ; 到队列 <点> ?

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);

Need to draw 2D graph the most easy way (I think - it's polyline) using MVVM pattern in WPF. I've created several classes:

    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
        }



    }
}

In the 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();
        }
    }

In MainWindow.xaml

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

    </Polyline>

 </Grid>

But it doesn't work.

EDIT:

I've wrote the following code, but I don't understand:

1) How do I bind
<Line X1="{Binding ??}" Y1="{Binding ??}" X2="{Binding ??}" Y2="{Binding ??}" Stroke="Red"/> to Queue < Point > ?

2)How can the < Line .../> refresh itself every second? Or how can the ViewModel refresh itself every second and notifies the View about it?

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);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

抱着落日 2024-10-24 23:31:27

使用 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>

这会产生这个“图表”:

裸骨图表

The easiest way to create a poor-man's chart in WPF using the MVVM pattern is to transform the data into a format that is easily consumable by markup, specifically segments instead of points.

Here is code representative of the view model:

    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 }))
        };
    }

and here is how to create a bare-bones chart from that data:

<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>

which results in this "chart":

bare bones chart

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文