Я пытаюсь создать элемент управления TextBox, который имеет «Таблицу значений» и «Индекс» в качестве свойств зависимостей, где я могу изменить свойство «Индекс», и TextBox будет искать соответствующее значение из таблицы.
Вот код:
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 свойства (таблица и индекс) инициализируются в случайном порядке, и всякий раз, когда индекс загружается перед таблицей, элемент управления не работает должным образом.
Есть ли обходной путь? Можем ли мы контролировать порядок инициализации или что-то еще, что я должен делать.
Буду очень признателен за отзыв
Спасибо
не выглядит ли itemsctrol более подходящим?
Реализация этого в элементе пользовательского интерфейса кажется странной идеей. Это должно быть сделано в модели представления или, возможно, в преобразователе привязки.
@LeiYang Мне просто нужна одна строка, а не вся таблица
@Clemens да, я просто пытаюсь сохранить простоту в этом примере
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);
}
}
Это прекрасно работает, большое спасибо
Что значит "не работает" в данном контексте?