我有一个UserControl
代表我对用户的自定义DataContext
。此控件还有DependencyProperty
(PropertyChangedCallback
),会影响DataContext
向用户显示的方式。
我的自定义UserControl
XAML:
<UserControl x:Class="WpfApplication1.MyControl"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
x:Name="Me">
<TextBox Text="{Binding FinalText,ElementName=Me}"/>
</UserControl>
我的自定义UserControl
代码:
using System.Diagnostics;
using System.Windows;
namespace WpfApplication1
{
public partial class MyControl
{
#region Static Fields and Constants
public static readonly DependencyProperty CapitalizeProperty = DependencyProperty.Register(nameof(Capitalize), typeof(bool),
typeof(MyControl), new PropertyMetadata(default(bool), CapitalizePropertyChanged));
public static readonly DependencyProperty FinalTextProperty =
DependencyProperty.Register(nameof(FinalText), typeof(string), typeof(MyControl), new PropertyMetadata(null));
#endregion
#region Properties and Indexers
public bool Capitalize
{
get => (bool)GetValue(CapitalizeProperty);
set => SetValue(CapitalizeProperty, value);
}
public string FinalText
{
get => (string)GetValue(FinalTextProperty);
set
{
Debug.WriteLine($"Setting {nameof(FinalText)} to value {value}");
SetValue(FinalTextProperty, value);
}
}
#endregion
#region Constructors
public MyControl()
{
InitializeComponent();
DataContextChanged += OnDataContextChanged;
}
#endregion
#region Private members
private static void CapitalizePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is MyControl me)
me.CreateFinalText(me.DataContext as string);
}
private void CreateFinalText(string text)
{
if (text != null)
{
FinalText = Capitalize ? text.ToUpperInvariant() : text.ToLowerInvariant();
}
else
{
FinalText = null;
}
}
private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs args)
{
CreateFinalText(args.NewValue as string);
}
#endregion
}
}
当我以下列方式使用UserControl
时:
<Grid>
<local:MyControl DataContext="Simple string" Capitalize="True"/>
</Grid>
我的调试输出显示以下内容:
将FinalText设置为值简单字符串
将FinalText设置为值SIMPLE STRING
我想知道在DependencyProperty
设置之前是否可以设置Capitalize
DataContext
?这样FinalText
属性就不会设置两次。
为了使我的问题更加复杂,我的实际UserControl
需要支持呈现Image
而不附加到Window
,这意味着Loaded
事件没有总是触发。
我可以添加正在使用的DependencyProperty
而不是DataContext
,但是仍然无法确保在我所有其他{{1}之后填充此新DependencyProperty
填充(示例中为DependencyProperties
)
修改
正如评论中指出的那样,不推荐使用Capitalize
,而是应该使用另一个DataContext
来设置需要呈现的内容。这很好,很容易做到,但是仍然无法保证在所有解析其他Property
后解析这个新Property
。
我想这个问题可以重新表述为:如何检测UserControl是否已经完全从XAML解析?
答案 0 :(得分:0)
我想知道在
Capitalize
设置之前是否可以设置DependencyPropertyDataContext
?
尝试更改顺序,即在设置Capitalize
属性之前设置DataContext
属性:
<local:MyControl Capitalize="True" DataContext="Simple string" />