我有一个单独的Window,其中ListBox和TextBlock绑定在一起(即master – > detail).然后我有一个带有几个属性的viewmodel – 一个字符串和一个日期.在这个日期,我实现了一个值转换器(LongDateConverter).
我在代码中有几个DeBUG.Writeline()调用,导致以下输出:
>启动应用
>在转换器中:ConverterProblem.MainWindowviewmodel
>在转换器中:null
>单击列表框中的两个项目之一
>在转换器中:ConverterProblem.DataModel
第二次和第三次调用IValueConverter方法我想我明白了.第二个为null,因为ListBox还没有选定的项目.第三个是我选择的项目.
我不明白的是:
>为什么第一个调用传递了MainWindowviewmodel类型的值?
>为什么这个电话甚至首先发生?
这是我的代码:
MainWindow.xaml:
<Window x:Class="ConverterProblem.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:app="clr-namespace:ConverterProblem" title="MainWindow" Height="350" WIDth="525"> <Window.Resources> <app:LongDateConverter x:Key="longDateConverter"/> </Window.Resources> <StackPanel OrIEntation="Horizontal"> <ListBox SelectedItem="{Binding Data}" ItemsSource="{Binding DataList}" displayMemberPath="name"/> <TextBlock Text="{Binding Converter={StaticResource longDateConverter}}" DataContext="{Binding Data}" /> </StackPanel></Window>
MainWindow.xaml.cs:
using System;using System.Collections.Generic;using System.ComponentModel;using System.Diagnostics;using System.Globalization;using System.windows;using System.windows.Data;namespace ConverterProblem { public class LongDateConverter : IValueConverter { public object Convert(object value,Type targettype,object parameter,CultureInfo culture) { if (value == null) { DeBUG.Writeline("In converter: null"); return "null"; } DeBUG.Writeline("In converter: " + value.GetType().ToString()); if (value.GetType() == typeof(MainWindowviewmodel)) return "viewmodel"; return ((DataModel)value).Date.TolongDateString(); } public object ConvertBack(object value,CultureInfo culture) { return null; } } public class DataModel { public string name { get; set; } public DateTime Date { get; set; } } public class MainWindowviewmodel : INotifyPropertyChanged { private DataModel _data; private List<DataModel> _dataList; public MainWindowviewmodel() { _dataList = new List<DataModel> { new DataModel { Date = DateTime.Now,name = "John" },new DataModel { Date = DateTime.Now.AddDays(50),name = "Sue" } }; } public DataModel Data { get { return _data; } set { if (_data == value) return; _data = value; RaisePropertyChanged("Data"); } } public List<DataModel> DataList { get { return _dataList; } } public event PropertyChangedEventHandler PropertyChanged; private voID RaisePropertyChanged(string propertyname) { var handler = PropertyChanged; if (handler != null) { handler(this,new PropertyChangedEventArgs(propertyname)); } } } public partial class MainWindow : Window { private MainWindowviewmodel _viewmodel; public MainWindow() { _viewmodel = new MainWindowviewmodel(); DataContext = _viewmodel; InitializeComponent(); } }}解决方法 问题是您在为TextBlock设置DataContext之前已绑定了Text依赖项.
XAML文件被编译成BAML,在应用程序运行时,它由BAML通过XAMLLoader加载,它从上到下解析XAML并相应地设置DP的值.
因为,首先遇到Text DP,所以它会尝试首先设置它的值,并且TextBlock尚未设置DataContext,因此它将继承其DataContext设置为MainWindowviewmodel的父窗口.因此,您会在转换器中看到MainWindowviewmodel.并且当设置DataContext时,将根据新的DataContext重新评估所有DP的绑定.
将您的XAML替换为此,您将看到MainWindowviewmodel将不再打印:
<TextBlock DataContext="{Binding Data}" Text="{Binding Converter={StaticResource longDateConverter}}" />
输出:
In converter: nullIn converter: ConverterProblem.DataModel总结
以上是内存溢出为你收集整理的c# – 了解WPF数据绑定和值转换器交互全部内容,希望文章能够帮你解决c# – 了解WPF数据绑定和值转换器交互所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)