代码之家  ›  专栏  ›  技术社区  ›  KrzysiekYESS

不知道如何绑定MVVM

  •  1
  • KrzysiekYESS  · 技术社区  · 1 年前

    我一直在学习如何使用MVVM制作第一个应用程序的教程,但我无法将ViewModel绑定到MainWindow,然后从屏幕上的中获取数据。我得到了2行空文本框(.json文件中有10个对象) 以下是我所做的:

    namespace MVVC.Model
    {
        public class CoffeeModel { }
    
        public class Coffee : INotifyPropertyChanged
        {
            [JsonProperty("coffee_type")]
            private string _type;
            [JsonProperty("price")]
            private double _price;
            [JsonProperty("roast_level")]
            private string _roast;
            [JsonProperty("origin_country")]
            private string _origin;
    
            public string type
            {
                get => _type;
                set
                {
                    if (value != _type)
                    {
                        _type = value;
                        RaisePropertyChanged("type");
                    }
                }
            }
    
            public double price
            {
                get => _price;
                set
                {
                    if (value != _price) 
                    {
                        _price = value;
                        RaisePropertyChanged("price");
                    }
                }
    
            }
    
            public string roast
            {
                get => _roast;
                set
                {
                    if(value != _roast)
                    {
                        _roast = value;
                        RaisePropertyChanged("roast");
                    }
                }
    
            }
    
            public string origin
            {
                get =>_origin;
                set
                {
                    if (_origin != value)
                    {
                        _origin = value;
                        RaisePropertyChanged("origin");
                    }
                }
            }
    
    
    
            public event PropertyChangedEventHandler? PropertyChanged;
            private void RaisePropertyChanged(string property)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(property));
                }
            }
        }
    
    
    
    namespace MVVC.ViewModel
    {
        public class CoffeeViewModel
        {
            public ObservableCollection<CoffeeModel> CoffeeList { get; set; } = new ObservableCollection<CoffeeModel>();
    
          
            public void LoadCoffee()
            {
    
                CoffeeList=new ObservableCollection<CoffeeModel>();
                string json = File.ReadAllText("CoffeeData.json");
                var CoffeeModels = JsonConvert.DeserializeObject<List<CoffeeModel>>(json);
                foreach(var coffee in CoffeeModels)
                {
                    CoffeeList.Add(coffee);
                }
            }
        }
    }
    
    
    namespace MVVC.Views
    {
        /// <summary>
        /// Interaction logic for CoffeeView.xaml
        /// </summary>
        public partial class CoffeeView : UserControl
        {
            public CoffeeView()
            {
                InitializeComponent();
            
            }
        }
    }
    
    

    我不知道我是否应该在这里选择DataContext ^我看不到这个文件的XAML,因为它说如果我绑定到这里,它会意外结束

    <UserControl x:Class="MVVC.Views.CoffeeView"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:MVVC.Views" 
                 mc:Ignorable="d" 
                 d:DesignHeight="450" d:DesignWidth="800">
        <Grid>
            <StackPanel HorizontalAlignment = "Left">
    
                <ItemsControl ItemsSource = "{Binding Path = CoffeeList}" >
    
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation = "Horizontal">
                                <TextBox Text = "{Binding Path = type, Mode = TwoWay}" 
                            Width = "100" Margin = "3 5 3 5"/>
    
                                <TextBox Text = "{Binding Path = price, Mode = TwoWay}" 
                            Width = "100" Margin = "0 5 3 5"/>
    
                                <TextBlock Text = "{Binding Path = roast, Mode = OneWay}" 
                            Margin = "0 5 3 5"/>
    
                            </StackPanel>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
    
                </ItemsControl>
    
            </StackPanel>
        </Grid>
    </UserControl>
    
    
    namespace MVVC
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void CoffeeViewControl_Loaded(object sender, RoutedEventArgs e)
            {
                MVVC.ViewModel.CoffeeViewModel coffeeViewModelObject= new ViewModel.CoffeeViewModel();
                coffeeViewModelObject.LoadCoffee();
    
                CoffeeViewControl.DataContext= coffeeViewModelObject;
            }
    
    
        }
    }
    
    1 回复  |  直到 1 年前
        1
  •  1
  •   SELA    1 年前

    实施您的 Coffee.cs 具有 INotifyPropertyChanged 以便相应地与如下视图进行通信:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using Newtonsoft.Json;
    
    namespace MVVM.Model
    {
        public class Coffee : INotifyPropertyChanged
        {
            private string _type;
            private double _price;
            private string _roast;
            private string _origin;
    
            [JsonProperty("coffee_type")]
            public string Type
            {
                get => _type;
                set
                {
                    if (value != _type)
                    {
                        _type = value;
                        RaisePropertyChanged(nameof(Type));
                    }
                }
            }
    
            [JsonProperty("price")]
            public double Price
            {
                get => _price;
                set
                {
                    if (value != _price)
                    {
                        _price = value;
                        RaisePropertyChanged(nameof(Price));
                    }
                }
            }
    
            [JsonProperty("roast_level")]
            public string Roast
            {
                get => _roast;
                set
                {
                    if (value != _roast)
                    {
                        _roast = value;
                        RaisePropertyChanged(nameof(Roast));
                    }
                }
            }
    
            [JsonProperty("origin_country")]
            public string Origin
            {
                get => _origin;
                set
                {
                    if (value != _origin)
                    {
                        _origin = value;
                        RaisePropertyChanged(nameof(Origin));
                    }
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            private void RaisePropertyChanged(string propertyName)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    更改您的 CoffeeViewModel.cs LoadCoffee 如下所示:

    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using Newtonsoft.Json;
    using MVVM.Model;
    
    
    namespace MVVM.ViewModel
    {
        public class CoffeeViewModel : INotifyPropertyChanged
        {
            private ObservableCollection<Coffee> _coffeeList;
    
            public ObservableCollection<Coffee> CoffeeList
            {
                get => _coffeeList;
                set
                {
                    if (value != _coffeeList)
                    {
                        _coffeeList = value;
                        RaisePropertyChanged(nameof(CoffeeList));
                    }
                }
            }
    
            public CoffeeViewModel()
            {
                LoadCoffee();
            }
    
            public void LoadCoffee()
            {
             string json = @"
              [
                { 'coffee_type': 'Espresso', 'price': 2.5, 'roast_level': 'Dark', 'origin_country': 'Italy' },
                { 'coffee_type': 'Latte', 'price': 3.0, 'roast_level': 'Medium', 'origin_country': 'France' }
              ]";
    
            var coffeeModels = JsonConvert.DeserializeObject<List<Coffee>>(json);
            CoffeeList = new ObservableCollection<Coffee>(coffeeModels);
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            private void RaisePropertyChanged(string propertyName)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    你的观点是这样的:

    <UserControl x:Class="MVVM.Views.CoffeeView"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 xmlns:local="clr-namespace:MVVM.Views"
                 mc:Ignorable="d"
                 d:DesignHeight="450" d:DesignWidth="800">
        <Grid>
            <StackPanel HorizontalAlignment="Left">
                <ItemsControl ItemsSource="{Binding Path=CoffeeList}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <TextBox Text="{Binding Path=Type, Mode=TwoWay}" Width="100" Margin="3 5 3 5"/>
                                <TextBox Text="{Binding Path=Price, Mode=TwoWay}" Width="100" Margin="0 5 3 5"/>
                                <TextBlock Text="{Binding Path=Roast, Mode=OneWay}" Margin="0 5 3 5"/>
                            </StackPanel>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </StackPanel>
        </Grid>
    </UserControl>
    

    最后别忘了设置 DataContext 属于 MainWindow CoffeeViewModel 如下所示:

    <Window x:Class="MVVM.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="450" Width="800">
        <Grid>
            <local:CoffeeView />
        </Grid>
    </Window>
    

    通过以上操作,您将能够将json中的数据绑定到viewModel