I’m trying to create a TextBox control that has a "Table of values" and an "Index" as dependency properties, were I can changed the Index property and the TextBox will look for the corresponding Value from the Table.
Here’s the code:
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);
}
}
And the XAML code is something like this:
<local:IndexedTextBox Table="{Binding ViewModelTable}" Index="1"/>
Sometimes is works, other times it won’t.
I noticed that the 2 properties (Table and Index) are being initialized in random order, and whenever the Index is loaded before the Table the control won’t work as expected.
Is there a workaround to that? Can we control the order of the Initialization or there any other thing I should be doing.
I’d greatly appreciate a feedback
Thanks
>Solution :
whenever the Index is loaded before the Table the control won’t work as expected …
So change the implementation to make it work by for example invoking the callback for both properties and check the state of the control before doing anything, e.g.:
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);
}
}