c# – 了解WPF数据绑定和值转换器交互

前端之家收集整理的这篇文章主要介绍了c# – 了解WPF数据绑定和值转换器交互前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图了解下面简化的repro代码背后的实际情况.

我有一个单独的Window,其中ListBox和TextBlock绑定在一起(即master – > detail).然后我有一个带有几个属性viewmodel – 一个字符串和一个日期.在这个日期,我实现了一个值转换器(LongDateConverter).

我在代码中有几个Debug.WriteLine()调用,导致以下输出

>启动应用

>在转换器中:ConverterProblem.MainWindowviewmodel
>在转换器中:null

>单击列表框中的两个项目之一

>在转换器中:ConverterProblem.DataModel

第二次和第三次调用IValueConverter方法我想我明白了.第二个为null,因为ListBox还没有选定的项目.第三个是我选择的项目.

我不明白的是:

>为什么第一个调用传递了MainWindowviewmodel类型的值?
>为什么这个电话甚至首先发生?

这是我的代码

MainWindow.xaml:

  1. <Window x:Class="ConverterProblem.MainWindow"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:app="clr-namespace:ConverterProblem"
  5. Title="MainWindow" Height="350" Width="525">
  6. <Window.Resources>
  7. <app:LongDateConverter x:Key="longDateConverter"/>
  8. </Window.Resources>
  9. <StackPanel Orientation="Horizontal">
  10. <ListBox SelectedItem="{Binding Data}" ItemsSource="{Binding DataList}"
  11. DisplayMemberPath="Name"/>
  12. <TextBlock Text="{Binding Converter={StaticResource longDateConverter}}"
  13. DataContext="{Binding Data}" />
  14. </StackPanel>
  15. </Window>

MainWindow.xaml.cs:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Diagnostics;
  5. using System.Globalization;
  6. using System.Windows;
  7. using System.Windows.Data;
  8.  
  9. namespace ConverterProblem
  10. {
  11. public class LongDateConverter : IValueConverter
  12. {
  13. public object Convert(object value,Type targetType,object parameter,CultureInfo culture)
  14. {
  15. if (value == null) {
  16. Debug.WriteLine("In converter: null");
  17. return "null";
  18. }
  19.  
  20. Debug.WriteLine("In converter: " + value.GetType().ToString());
  21.  
  22. if (value.GetType() == typeof(MainWindowviewmodel))
  23. return "viewmodel";
  24.  
  25. return ((DataModel)value).Date.ToLongDateString();
  26. }
  27.  
  28. public object ConvertBack(object value,CultureInfo culture)
  29. {
  30. return null;
  31. }
  32. }
  33.  
  34. public class DataModel
  35. {
  36. public string Name { get; set; }
  37. public DateTime Date { get; set; }
  38. }
  39.  
  40. public class MainWindowviewmodel : INotifyPropertyChanged
  41. {
  42. private DataModel _data;
  43. private List<DataModel> _dataList;
  44.  
  45. public MainWindowviewmodel()
  46. {
  47. _dataList = new List<DataModel> {
  48. new DataModel { Date = DateTime.Now,Name = "John" },new DataModel { Date = DateTime.Now.AddDays(50),Name = "Sue" }
  49. };
  50. }
  51.  
  52. public DataModel Data
  53. {
  54. get { return _data; }
  55. set
  56. {
  57. if (_data == value) return;
  58.  
  59. _data = value;
  60. RaisePropertyChanged("Data");
  61. }
  62. }
  63.  
  64. public List<DataModel> DataList
  65. {
  66. get { return _dataList; }
  67. }
  68.  
  69. public event PropertyChangedEventHandler PropertyChanged;
  70. private void RaisePropertyChanged(string propertyName)
  71. {
  72. var handler = PropertyChanged;
  73. if (handler != null) {
  74. handler(this,new PropertyChangedEventArgs(propertyName));
  75. }
  76. }
  77. }
  78.  
  79. public partial class MainWindow : Window
  80. {
  81. private MainWindowviewmodel _viewmodel;
  82.  
  83. public MainWindow()
  84. {
  85. _viewmodel = new MainWindowviewmodel();
  86. DataContext = _viewmodel;
  87. InitializeComponent();
  88. }
  89. }
  90. }

解决方法

问题是您在为TextBlock设置DataContext之前已绑定了Text依赖项.

XAML文件被编译成BAML,在应用程序运行时,它由BAML通过XAMLLoader加载,它从上到下解析XAML并相应地设置DP的值.

因为,首先遇到Text DP,所以它会尝试首先设置它的值,并且TextBlock尚未设置DataContext,因此它将继承其DataContext设置为MainWindowviewmodel的父窗口.因此,您会在转换器中看到MainWindowviewmodel.并且当设置DataContext时,将根据新的DataContext重新评估所有DP的绑定.

将您的XAML替换为此,您将看到MainWindowviewmodel将不再打印:

  1. <TextBlock DataContext="{Binding Data}"
  2. Text="{Binding Converter={StaticResource longDateConverter}}" />

输出

  1. In converter: null
  2. In converter: ConverterProblem.DataModel

猜你在找的C#相关文章