WPF C# MVVM -无法在数据库结果后更新绑定

lvmkulzt  于 2023-10-16  发布在  C#
关注(0)|答案(1)|浏览(197)

我正在尝试使用MVVM模型创建WPF应用程序。
目前我被以下几点卡住了;
在应用程序中,有一个选项可以搜索一个数字(注册号),没有什么花哨的只是一个文本框。
当用户按下“搜索”时,我不想将数据从数据库加载到模型中,并将其显示在用户控件上。
这是我的主窗口视图模型

  1. public class MainWindowViewModal : ViewModelBase
  2. {
  3. //Fields
  4. private string _zoekenUitvaartnummer;
  5. private string _zoekenAchternaam;
  6. private string _zoekenGeboortedatum;
  7. private bool _volgendePagina = false;
  8. private IOverledeneRepository overledeneRepository;
  9. //Properties
  10. public string ZoekenUitvaartnummer
  11. {
  12. get => _zoekenUitvaartnummer;
  13. set
  14. {
  15. _zoekenUitvaartnummer = value;
  16. OnPropertyChanged(nameof(ZoekenUitvaartnummer));
  17. }
  18. }
  19. //->Commands
  20. public ICommand SearchUitvaartnummerCommand { get; }
  21. public MainWindowViewModal()
  22. {
  23. overledeneRepository = new OverledeneRepository();
  24. SearchUitvaartnummerCommand = new ViewModelCommand(ExecuteSearchUitvaartnummerCommand, CanExecuteSearchUitvaartnummerCommand);
  25. SearchAchternaamCommand = new ViewModelCommand(ExecuteSearchAchternaamCommand, CanExecuteSearchAchternaamCommand);
  26. }
  27. private bool CanExecuteSearchUitvaartnummerCommand(object obj)
  28. {
  29. bool validNummerSearch;
  30. if(string.IsNullOrWhiteSpace(ZoekenUitvaartnummer))
  31. {
  32. validNummerSearch = false;
  33. }
  34. else
  35. {
  36. validNummerSearch = true;
  37. }
  38. return validNummerSearch;
  39. }
  40. private void ExecuteSearchUitvaartnummerCommand(object obj)
  41. {
  42. var SearchUitvaartleider = overledeneRepository.GetUitvaarleiderByUitvaartId(ZoekenUitvaartnummer);
  43. OverledeneViewModel.Instance.LoadCurrentUitvaartLeider(ZoekenUitvaartnummer);
  44. }
  45. }

在overledeneRepository.GetUitvaarleiderByUitvaartId(ZoekenUitvaartnummer)上调用数据库

  1. public class OverledeneRepository : RepositoryBase, IOverledeneRepository
  2. {
  3. public OverledeneUitvaartleiderModel GetUitvaarleiderByUitvaartId(string uitvaartId)
  4. {
  5. OverledeneUitvaartleiderModel uitvaartLeiderGegevens = null;
  6. using (var connection = GetConnection())
  7. using (var command = new SqlCommand())
  8. {
  9. connection.Open();
  10. command.Connection = connection;
  11. command.CommandText = "SELECT UitvaartId, CONCAT(Initialen,' ',Achternaam) as PersoneelName, PersoneelId, Uitvaartnummer " +
  12. " FROM OverledeneUitvaartleider" +
  13. " INNER JOIN ConfigurationPersoneel ON PersoneelId = Id" +
  14. " WHERE Uitvaartnummer=@uitvaartNummer";
  15. command.Parameters.Add("@uitvaartNummer", System.Data.SqlDbType.VarChar).Value = uitvaartId;
  16. using (var reader = command.ExecuteReader())
  17. {
  18. if (reader.Read())
  19. {
  20. uitvaartLeiderGegevens = new OverledeneUitvaartleiderModel()
  21. {
  22. UitvaartId = (Guid)reader[0],
  23. PersoneelNaam = reader[1].ToString(),
  24. PersoneelId = (Guid)reader[2],
  25. Uitvaartnummer = reader[3].ToString(),
  26. };
  27. }
  28. }
  29. }
  30. return uitvaartLeiderGegevens;
  31. }
  32. }

返回的值被解析为视图模型

  1. public class OverledeneViewModel : ViewModelBase
  2. {
  3. //Fields
  4. private string _uitvaartNummer;
  5. private string _uitvaartLeider;
  6. private IOverledeneRepository overledeneRepository;
  7. private OverledeneUitvaartleiderModel _uitvaartLeiderModel;
  8. //Properties
  9. public OverledeneUitvaartleiderModel UitvaartLeiderInfo
  10. {
  11. get
  12. {
  13. return _uitvaartLeiderModel;
  14. }
  15. set
  16. {
  17. _uitvaartLeiderModel = value;
  18. OnPropertyChanged(nameof(UitvaartLeiderInfo));
  19. }
  20. }
  21. private OverledeneViewModel()
  22. {
  23. overledeneRepository = new OverledeneRepository();
  24. UitvaartLeiderInfo = new OverledeneUitvaartleiderModel();
  25. SaveCommand = new ViewModelCommand(ExecuteSaveCommand, CanExecuteSaveCommand);
  26. }
  27. public static OverledeneViewModel Instance {get;} = new();
  28. public void LoadCurrentUitvaartLeider(string uitvaartNummer)
  29. {
  30. var UitvaarLeiderResult = overledeneRepository.GetUitvaarleiderByUitvaartId(uitvaartNummer);
  31. if (UitvaarLeiderResult != null)
  32. {
  33. UitvaartLeiderInfo.Uitvaartnummer = UitvaarLeiderResult.Uitvaartnummer;
  34. UitvaartLeiderInfo.PersoneelNaam = UitvaarLeiderResult.PersoneelNaam;
  35. }
  36. }
  37. }

有了这个模型

  1. public class OverledeneUitvaartleiderModel
  2. {
  3. public Guid UitvaartId { get; set; }
  4. public Guid PersoneelId { get; set; }
  5. public string PersoneelNaam { get; set; }
  6. public string Uitvaartnummer { get; set; }
  7. }

最后,这是我希望数据可见的xaml

  1. <UserControl x:Class="Test.Views.OverledeneView"
  2. xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
  5. xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
  6. xmlns:local="clr-namespace:Test.ViewModels"
  7. mc:Ignorable = "d"
  8. d:DesignHeight="696.96" d:DesignWidth="1190.257"
  9. DataContext="{x:Static local:OverledeneViewModel.Instance}">
  10. <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
  11. <Grid x:Name="GridOverledeneView" Background="White" ScrollViewer.CanContentScroll="True">
  12. <TextBox x:Name="input_UitvaartNrOverledene" Text="{Binding Path=uitvaartLeiderModel.Uitvaartnummer, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" TabIndex="1" VerticalContentAlignment="Center" HorizontalAlignment="Left" Margin="204,14,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="301" Height="31" FontSize="16" SelectionBrush="#FFD70000" FontFamily="Arial" BindingGroup="{Binding Text, ElementName=UitvaartLeider}"/>
  13. </Grid>
  14. </ScrollViewer>
  15. </UserControl>

这是ViewModelBase

  1. public abstract class ViewModelBase : INotifyPropertyChanged
  2. {
  3. public event PropertyChangedEventHandler PropertyChanged;
  4. public void OnPropertyChanged(string propertyName)
  5. {
  6. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  7. }
  8. }

我做错了什么?
谁能帮我解释一下我做错了什么?
任何帮助都将不胜感激。
帕特里克

nwsw7zdq

nwsw7zdq1#

最有可能的是,您在OverledeneViewModel类的示例中有混淆。在MainWindowViewModal.ExecuteSearchUitvaartnummerCommand方法中,创建OverledeneViewModel的第一个示例。并在此示例上运行验证方法。

  1. private void ExecuteSearchUitvaartnummerCommand(object obj)
  2. {
  3. var SearchUitvaartleider = overledeneRepository.GetUitvaarleiderByUitvaartId(ZoekenUitvaartnummer);
  4. var DL = new OverledeneViewModel();
  5. DL.LoadCurrentUitvaartLeider(ZoekenUitvaartnummer);
  6. }

OverledeneView View类的XAML中,创建另一个处于初始不可变状态的OverledeneViewModel示例。

  1. <UserControl.DataContext>
  2. <local:OverledeneViewModel/>
  3. </UserControl.DataContext>

如果您不需要同时使用OverledeneViewModel的多个示例,请尝试使用Singleton。范例:

  1. public class OverledeneViewModel : ViewModelBase
  2. {
  3. // Some Code
  4. // Hiding the constructor
  5. private OverledeneViewModel()
  6. {
  7. overledeneRepository = new OverledeneRepository();
  8. UitvaartLeiderInfo = new OverledeneUitvaartleiderModel();
  9. SaveCommand = new ViewModelCommand(ExecuteSaveCommand, CanExecuteSaveCommand);
  10. }
  11. // The only instance available
  12. public static OverledeneViewModel Instance {get;} = new();
  13. }
  1. private void ExecuteSearchUitvaartnummerCommand(object obj)
  2. {
  3. var SearchUitvaartleider = overledeneRepository.GetUitvaarleiderByUitvaartId(ZoekenUitvaartnummer);
  4. // var DL = new OverledeneViewModel();
  5. OverledeneViewModel.Instance.LoadCurrentUitvaartLeider(ZoekenUitvaartnummer);
  6. }
  1. <UserControl x:Class="Test.Views.OverledeneView"
  2. xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
  5. xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
  6. xmlns:local="clr-namespace:Test.ViewModels"
  7. mc:Ignorable = "d"
  8. d:DesignHeight="696.96" d:DesignWidth="1190.257"
  9. DataContext={x:Static local:OverledeneViewModel.Instance}>
  10. <!--<UserControl.DataContext>
  11. <local:OverledeneViewModel/>
  12. </UserControl.DataContext>-->

当我把结果放在消息框中时,它显示为1234,也许绑定在某个地方关闭了?真的迷失在这里
我没有马上注意到第二个错误。
在“OverledeneView”中,您已经设置了绑定:

  1. <TextBox x:Name="input_UitvaartNrOverledene"
  2. Text="{Binding Path=uitvaartLeiderModel.Uitvaartnummer, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
  3. -----/>

但是,在类“OverledeneViewModel”中没有属性“uitvaartLeiderModel”。
我认为你需要一个这样的约束力:

  1. <TextBox x:Name="input_UitvaartNrOverledene"
  2. Text="{Binding UitvaartLeiderInfo.Uitvaartnummer, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
  3. -----/>

**P.S.**这里也有关于“OverledeneUitvaartleiderModel”类实现的注解。它没有INotifyPropertyChanged的实现,这意味着当它的属性更改时,视图不会自动更新。我认为你最好用只读结构替换这个类。

展开查看全部

相关问题