你是对的! DataContextChanged 事件的 EventArgs 没有提供我们可以从中获取旧 DataContext 值的属性。
但是由于您正在创建自定义控件,我认为一个干净的选项可能是在您的自定义控件上注册一个自定义依赖项属性,其唯一目的是存储旧的DataContext 值,每当@987654325 时更新@事件发生。
所以我首先定义了一个名为 CustomUserControl 的 UserControl:
public sealed partial class CustomUserControl : UserControl
{
public CustomUserControl()
{
this.InitializeComponent();
}
public static readonly DependencyProperty OldDataContextProperty =
DependencyProperty.Register(
"OldDataContext",
typeof(object),
typeof(CustomUserControl),
new PropertyMetadata(null)
);
public object OldDataContext
{
get
{
return GetValue(OldDataContextProperty);
}
set
{
SetValue(OldDataContextProperty, value);
}
}
private void RootObject_DataContextChanged(FrameworkElement sender,
DataContextChangedEventArgs args)
{
System.Diagnostics.Debug.WriteLine("Old Data Context: " + OldDataContext);
System.Diagnostics.Debug.WriteLine("New Data Context: " + DataContext);
OldDataContext = args.NewValue;
}
}
每当发生DataContextChanged 事件时,我们首先分析设置为自定义控件的旧/新DataContext 的对象的类型,只需通过OldDataContext 属性访问自定义依赖属性OldDataContextProperty .
用户控件的布局相当简单,由单个ComboBox(可以是其他任何东西)组成,它暴露了DataContextChanged事件,其事件处理程序在上面定义:
<UserControl
x:Class="UserControlForStackOverflow.CustomUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UserControlForStackOverflow"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<ComboBox x:Name="RootObject" DataContextChanged="RootObject_DataContextChanged" />
</UserControl>
在 MainPage 的布局中,我实例化了这个自定义用户控件:
<Page
x:Class="UserControlForStackOverflow.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UserControlForStackOverflow"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<local:CustomUserControl x:Name="CustomControl" />
</Page>
在代码隐藏中,我初始化了两种类型的 Lists 变量,一种类型为string,另一种类型为int,以了解OldDataContextProperty 依赖属性是否按预期工作。
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
List<string> list1 = new List<string> { "aaa", "bbb", "ccc" };
List<int> list2 = new List<int> { 1, 2, 3 };
CustomControl.DataContext = list1;
CustomControl.DataContext = list2;
}
}
结果是假装的:
旧数据上下文:
新数据上下文: System.Collections.Generic.List`1[System.String]
旧数据上下文: System.Collections.Generic.List`1[System.String]
新数据上下文: System.Collections.Generic.List`1[System.Int32]
当我们第一次触发 DataContextChanged 事件时,OldDataContextProperty 保存默认值,即 null(在 PropertyMetaData 构造函数中指定的值),而当前的 DataContext 属性设置为第一个 List 集合。
当我们将自定义控件的DataContext 更改为保存第二个列表时,我们可以看到OldDataContextProperty 仍然引用了设置为控件的DataContext 的第一个对象,并将保持对它的引用,直到执行到达RootObject_DataContextChanged EventHandler 的末尾,其中OldDataContextProperty 将设置为当前DataContext 值。
您只需在此更新之前执行所需的操作。