c# - 试图理解 MVVM 数据不断重置
问题描述
目标:当我在技术人员姓名的文本框中输入一个值时:我希望它在 DataModel 中更新,当我单击 NewCallView 时,它将显示在 newcall 视图中,当我单击返回 DefaultViewModel 时,它仍将显示为已输入。
问题:当我在视图之间更改时,数据会重置。
我将提供我的完整代码,以找出我的数据不断重置的原因。- 我还在学习 MVVM,这是我的第一次尝试。我通常会使用代码隐藏制作一个 1 页的应用程序。我发现很难将我的模型链接到我的视图模型,也许我错误地调用(获取/设置)属性。
关于我的每个视图背后的代码,我根本没有改变它的创建,我只在 Xaml 中工作。
主窗口代码隐藏
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using callFlow.ViewModels;
using callFlow.Models;
namespace callFlow
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void DefaultViewClicked(object sender, RoutedEventArgs e)
{
DataContext = new DefaultViewModel();
}
private void NewCallClicked(object sender, RoutedEventArgs e)
{
DataContext = new NewCallViewModel();
}
}
}
主窗口视图 / wpf
<Window x:Class="callFlow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:callFlow"
xmlns:viewmodels="clr-namespace:callFlow.ViewModels"
xmlns:views="clr-namespace:callFlow.Views"
mc:Ignorable="d"
Title="Call FLow Management" Height="728" Width="1260">
<Window.Resources>
<DataTemplate x:Name="defaultViewTemplate" DataType="{x:Type viewmodels:DefaultViewModel}">
<views:DefaultView DataContext="{Binding}"/>
</DataTemplate>
<DataTemplate x:Name="newCallViewTemplate" DataType="{x:Type viewmodels:NewCallViewModel}">
<views:NewCallView DataContext="{Binding}"/>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="5" Grid.RowSpan="6" Background="
{DynamicResource {x:Static SystemColors.MenuBrushKey}}"/>
<Grid Grid.Row="1" Grid.Column="0" Grid.RowSpan="6" />
<Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="6" Background="FloralWhite">
<Image Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" Source="/BofA2.png" Width="400"
HorizontalAlignment="Left" />
<Border BorderThickness="1" BorderBrush="Black" Grid.Column="0" Grid.Row="0"
Grid.ColumnSpan="6" CornerRadius="8 8 8 8"/>
<Border BorderThickness="1" BorderBrush="Black" Grid.Column="0" Grid.Row="1"
Grid.RowSpan="6"
CornerRadius="8 8 8 8"/>
</Grid>
<StackPanel Grid.Row="1" Grid.Column="0" Grid.RowSpan="6">
<Button Name="loadDefaultView" Content="Home" Grid.Column="2" Grid.Row="2" Height="40"
Margin="5 5 5 5" Click="DefaultViewClicked" > </Button>
<Button Name="loadNewCall" Content="New Call" Grid.Column="2" Grid.Row="2" Height="40"
Margin="5 0 5 0 " Click="NewCallClicked" ></Button>
</StackPanel>
<ContentControl Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="6" Grid.RowSpan="6" Content="
{Binding}">
</ContentControl>
</Grid>
</Window>
视图/DefaultView.xaml
<UserControl x:Class="callFlow.Views.DefaultView"
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:callFlow.Views"
xmlns:viewmodels="clr-namespace:callFlow.ViewModels"
xmlns:model="clr-namespace:callFlow.Models"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="FloralWhite">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.ColumnSpan="7" Margin="0 10 0 0" HorizontalAlignment="Center"
Text="Call Flow Management" TextWrapping="Wrap" FontSize="24" VerticalAlignment="Top"/>
<StackPanel Grid.Row="0" Grid.Column="5" Grid.ColumnSpan="1" Margin="0 5 0 0">
<TextBlock HorizontalAlignment="Left" Grid.Column="0" Grid.Row="1" Text="Technician Name: "
FontSize="14" TextWrapping="Wrap" Grid.ColumnSpan="2" Width="134"/>
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="6" Grid.ColumnSpan="1" Margin="5 5 5 0">
<TextBox Name="techName" Text="{Binding SelectedModel.TechName,Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" BorderBrush="#FF4A5780" Grid.RowSpan="2" />
</StackPanel>
<TextBlock x:Name="TextUpdate" Grid.Column="5" HorizontalAlignment="Left" Margin="41,0,0,0"
Grid.Row="1" Text="{Binding SelectedModel.TechName}" TextWrapping="Wrap" VerticalAlignment="Center"/>
</Grid>
</UserControl>
ViewModels/DefaultViewModel.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using callFlow.Models;
namespace callFlow.ViewModels
{
public class DefaultViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public DefaultViewModel() { }
private ObservableCollection<DataModel> model = new ObservableCollection<DataModel>();
private DataModel _SelectedModel;
public DataModel SelectedModel
{
get { return _SelectedModel ?? (_SelectedModel = new DataModel()); }
set { _SelectedModel = value; OnPropertyChanged(); }
}
public void changeSelectedModel(DataModel newSelectedModel)
{
SelectedModel.TechName = newSelectedModel.TechName;
}
private void OnPropertyChanged([CallerMemberName] string techName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(techName));
}
}
}
视图\NewCallView.xaml
<UserControl x:Class="callFlow.Views.NewCallView"
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:callFlow.Views"
xmlns:viewmodels="clr-namespace:callFlow.ViewModels"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="#FFFDFDFD">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock x:Name="techNameSet" Grid.Column="2" HorizontalAlignment="Left" Margin="40,52,0,0"
Grid.Row="2" Text="{Binding SelectedModel.TechName}" TextWrapping="Wrap" VerticalAlignment="Top"
Grid.ColumnSpan="2" Width="114"/>
</Grid>
</UserControl>
NewCallViewModel.cs
namespace callFlow.ViewModels
{
class NewCallViewModel
{
//It's empty, my view is calling SelectedModel.TechName from DataViewModel which works when I update the DataModel Directly
}
}
最后但并非最不重要的!!!!
模型/DataModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using System.Drawing;
namespace callFlow.Models
{
public class DataModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string techName;
public DataModel()
{
}
public string TechName
{
get { return techName; }
set { techName = value; OnPropertyChanged(); }
}
private void OnPropertyChanged([CallerMemberName] string techName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(techName));
}
}
}
解决方案
推荐阅读
- python - 如何在递归函数中保持值不变?
- google-cloud-platform - CloudRun 正在超过最大实例数(共 1 个)
- go - 使用等待组的 Golang 工作者
- javascript - 如何添加不与更新内容功能冲突的自动图像幻灯片放映
- python - pd.DataFrame 上的 for 循环继续运行,但在 100 次迭代后停止工作
- php - 如何插入或更新来自不同表的记录
- arrays - C char 数组在赋值循环后丢失指针
- azure-data-factory - Azure 数据工厂 - 不安然后删除
- c# - 如何在 C# 中使用 sendgrid 添加回复
- python - 我喜欢从双重列表中消除重复的组件,然后合并双重列表