Я сейчас занимаюсь учебным проектом. Он должен преобразовывать числа в разные строки. Heres преобразованный элемент управления, а в нижней части я использую его в своем главном окне. Итак, первая проблема заключается в том, что я хочу создать экземпляр конвертера на основе значения, которое я передаю OutputFormatProperty, поэтому в этом случае я создаю конвертер, который должен быть типом OctalConverter, но вместо этого я получаю значение по умолчанию, почему? Другое дело, что я не буду изменять InputValue в конвертере, привязывая его к CurrentValue, который работает с NotifyPropertyChanged, но похоже, что это не так.Когда применяется свойство зависимостей?
public partial class ConverterDisplay : UserControl {
private const int DEFAULT_INPUT_VALUE = 0;
private readonly ObservableCollection <DisplayField> _displayFields;
private AbstractNumberConverter _converter;
public static readonly DependencyProperty InputValueProperty = DependencyProperty.Register (
"InputValue",
typeof(int),
typeof(ConverterDisplay),
new PropertyMetadata (DEFAULT_INPUT_VALUE));
public static readonly DependencyProperty OutputFormatProperty = DependencyProperty.Register (
"OutputFormat",
typeof(NumberSystems),
typeof(ConverterDisplay),
new FrameworkPropertyMetadata (NumberSystems.Binary));
public int InputValue {
get {
return (int) GetValue (InputValueProperty);
}
set {
SetValue (InputValueProperty, value);
UpdateDisplay();
}
}
public NumberSystems OutputFormat {
get {
return (NumberSystems) GetValue (OutputFormatProperty);
}
set {
SetValue (OutputFormatProperty, value);
}
}
public ObservableCollection <DisplayField> DisplayFields {
get { return _displayFields; }
}
public ConverterDisplay() {
_displayFields = new ObservableCollection<DisplayField>();
InitializeComponent();
CreateConverter();
}
private void UpdateDisplay() {
var convertedNumberString = _converter.GetString (InputValue);
if (_displayFields.Count > convertedNumberString.Length)
ResetDisplayFields();
while (_displayFields.Count < convertedNumberString.Length)
AddDisplayField();
UpdateValues (convertedNumberString);
}
private void UpdateValues (string convertedString) {
if (_displayFields.Count == 0) return;
for (int i = 0; i < _displayFields.Count; i++) {
_displayFields [i].NumberValue = convertedString [i];
}
}
private void AddDisplayField() {
_displayFields.Insert (
0,
new DisplayField ((int)OutputFormat, _displayFields.Count));
}
private void ResetDisplayFields() {
_displayFields.Clear();
}
private void CreateConverter() {
switch (OutputFormat) {
case NumberSystems.Binary:
_converter = new BinaryConverter();
break;
case NumberSystems.Octal:
_converter = new OctalConverter();
break;
case NumberSystems.Hexadecimal:
_converter = new HexadecimalConverter();
break;
}
}
}
public enum NumberSystems {
Binary = 2,
Octal = 8,
Hexadecimal = 16
}
А потом в главном окне я пытаюсь использовать этот контроль
<converters:ConverterDisplay x:Name="octConverter"
InputValue="{Binding ElementName=Window,Path=CurrentValue}"
OutputFormat="Octal"/>
Только в случае
public int CurrentValue {
get { return _currentValue; }
set {
if (value == _currentValue)
return;
ValidateNewValue (value);
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged ([CallerMemberName] string propertyName = null) {
PropertyChanged?.Invoke (this, new PropertyChangedEventArgs (propertyName));
}
============ ===============
Редактировать # 1
Мне не очень нравится это решение, но я создал публичный метод в ConverterDisplay для создания конвертера, он вызывается после того, как MainWindow инициализирован, поэтому теперь преобразователи верны. Другое дело, как связать мой метод UpdateDisplay с InputValueProperty? Я нашел подтверждение, что оно получает правильное значение, но я не могу понять, как я могу запустить этот метод без создания статического материала.
Спасибо! То, как я это сделаю, я думаю, что я также воспользуюсь этим решением для создания разных NumberConverters, когда значение в OutputFormatProperty изменится, поэтому у меня нет вызова из кода внутри MainWinow:] – yoger