代码之家  ›  专栏  ›  技术社区  ›  ManIkWeet

在设置影响DataContext表示的属性之前设置WPF DataContext

  •  0
  • ManIkWeet  · 技术社区  · 6 年前

    我有一个 UserControl 代表我的习惯 DataContext 给用户。此控件还具有 DependencyProperty (带有 PropertyChangedCallback )这会影响 数据上下文 向用户显示。

    我的自定义 用户控件 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>
    

    我的自定义 用户控件 代码隐藏:

    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
        }
    }
    

    当我使用 用户控件 按以下方式:

    <Grid>
        <local:MyControl DataContext="Simple string" Capitalize="True"/>
    </Grid>
    

    我的调试输出显示以下内容:

    将FinalText设置为value simple string
    将FinalText设置为value SIMPLE STRING

    我想知道是否有可能 关联属性 Capitalize 设置在 数据上下文 是否已设置?那样的话 FinalText 属性未设置两次。

    让我的问题更复杂一点 用户控件 需要支持渲染到 Image 没有连接到 Window ,表示 Loaded 事件并不总是触发。

    我可以添加一个 关联属性 而不是 ,但仍然无法确保 关联属性 在我的所有其他 DependencyProperties 已填充( 资本化 在示例中)

    编辑:
    正如评论中所指出的,使用 数据上下文 不建议使用,我应该使用另一个 Property 所有物 在之后分析 全部的 其他的 Properties 已分析。
    我想这个问题可以重新表述为: 如何检测用户控件是否已从XAML完全解析?

    1 回复  |  直到 6 年前
        1
  •  0
  •   mm8    6 年前

    我想知道是否有可能拥有DependencyProperty Capitalize 设置在 DataContext 是否已设置?

    尝试更改顺序,即设置 资本化 属性,然后再设置 数据上下文 属性:

    <local:MyControl Capitalize="True" DataContext="Simple string" />