C#中如何控制依赖属性初始化的顺序

How to control the order of Dependecy Properties Initialization in C#

我正在尝试创建一个具有“Table 个值”和一个“索引”作为依赖属性的 TextBox 控件,如果我可以更改索引 属性 并且 TextBox 将从 Table.

中寻找相应的值

代码如下:

public class Record
{
    public int Index { get; set; }
    public string Value { get; set; }
}
public class IndexedTextBox : TextBox
{
    public static readonly DependencyProperty TableProperty = DependencyProperty.Register(nameof(Table),
                    typeof(IEnumerable<Record>), typeof(IndexedTextBox));
    public static readonly DependencyProperty IndexProperty = DependencyProperty.Register(nameof(Index),
                    typeof(int), typeof(IndexedTextBox), new PropertyMetadata(0, IndexChangedCallback));

    private static void IndexChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        IndexedTextBox ctl = d as IndexedTextBox;
        int index = (int)e.NewValue;

        if (ctl.Table.Any(t => t.Index == index))
            ctl.Text = ctl.Table.Where(t => t.Index == index).FirstOrDefault().Value;
        else
            ctl.Text = "N/A";
    }

    public IEnumerable<Record> Table
    {
        get => (IEnumerable<Record>)GetValue(TableProperty);
        set => SetValue(TableProperty, value);
    }

    public int Index {
        get => (int)GetValue(IndexProperty);
        set => SetValue(IndexProperty, value);
    }
}

而 XAML 代码是这样的:

<local:IndexedTextBox Table="{Binding ViewModelTable}" Index="1"/>

有时有效,有时无效。

我注意到 2 个属性(Table 和索引)正在以随机顺序初始化,只要索引在 Table 之前加载,控件就不会按预期工作。

有解决办法吗?我们可以控制初始化的顺序还是我应该做的任何其他事情。

非常感谢您的反馈

谢谢

whenever the Index is loaded before the Table the control won't work as expected ...

因此更改实现以使其工作,例如通过调用两个属性的回调并在执行任何操作之前检查控件的状态,例如:

public class IndexedTextBox : TextBox
{
    public static readonly DependencyProperty TableProperty = DependencyProperty.Register(nameof(Table),
                    typeof(IEnumerable<Record>), typeof(IndexedTextBox), new PropertyMetadata(null, TableChangedCallback));

    public static readonly DependencyProperty IndexProperty = DependencyProperty.Register(nameof(Index),
                    typeof(int), typeof(IndexedTextBox), new PropertyMetadata(0, IndexChangedCallback));

    private static void TableChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) =>
        ((IndexedTextBox)d).SetText();

    private static void IndexChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) =>
        ((IndexedTextBox)d).SetText();

    private void SetText()
    {
        if (Table != null)
        {
            int index = Index;

            if (Table.Any(t => t.Index == index))
                Text = Table.Where(t => t.Index == index).FirstOrDefault().Value;
            else
                Text = "N/A";
        }
    }

    public IEnumerable<Record> Table
    {
        get => (IEnumerable<Record>)GetValue(TableProperty);
        set => SetValue(TableProperty, value);
    }

    public int Index
    {
        get => (int)GetValue(IndexProperty);
        set => SetValue(IndexProperty, value);
    }
}