Скажем, у меня есть этот контроль:

public partial class bloc999 : UserControl
{
 bloc999Data mainBlock = new bloc999Data();

 public bloc999()
 {
  InitializeComponent();
  mainBlock.txtContents = "100";

  base.DataContext = mainBlock;
 }
}

В xaml:

    <TextBox Margin="74,116,106,0" Name="txtContents" 
Text="{Binding Path=txtContents, UpdateSourceTrigger=PropertyChanged,Mode = TwoWay}" />
    <TextBox Margin="74,145,106,132" Name="txtContents2" 
Text="{Binding Path=txtContents2, UpdateSourceTrigger=PropertyChanged,Mode = TwoWay}" />

Тогда у меня есть этот класс:

public class bloc999Data : INotifyPropertyChanged
    {
     string _txtContents;
     string _txtContents2;

     public event PropertyChangedEventHandler PropertyChanged;

     void NotifyPropertyChanged(string propName)
     {
            if (this.PropertyChanged != null)
                this.PropertyChanged(
                    this, new PropertyChangedEventArgs(propName));
     }

     public string txtContents2
     {
            get
            {
              return this._txtContents2;
            }
            set
            {
                if (int.Parse(value) > int.Parse(this._txtContents))
                {
                    this._txtContents2 = "000";
                }
                else
                    this._txtContents2 = value;

                NotifyPropertyChanged("txtContents2");
            }
        }

        public string txtContents 
        {
            get
            {
                return this._txtContents;
            }
            set 
            {
                this._txtContents = value;
                NotifyPropertyChanged("txtContents");
            } 
        }
    }

Хорошо, теперь скажем, что у меня есть кнопка в форме, и я делаю это в коде:

mainBlock.txtContents2 = "7777777";

Он помещает 000 в текстовое поле, но если я просто набираю вручную в текстовое поле (txtContents2), вызывается код установщика, но по какой-то причине значение текстовых полей не изменяется, значение экземпляра изменяется. помощь?

0
Enriquev 31 Мар 2010 в 21:49

2 ответа

Лучший ответ

Я считаю, что это просто потому, что значение изменяется в контексте операции привязки данных, поэтому WPF просто игнорирует его, потому что знает, что значение изменяется , и считает событие излишним. Он не знает, что вы снова изменили значение WPF на другое.

Если вы сделаете уведомление в отдельном сообщении, WPF обработает его вне контекста текущей операции привязки данных и, таким образом, примет изменение:

if (int.Parse(value) > int.Parse(this._txtContents))
{
    this._txtContents2 = "000";

    // notify WPF of our change to the property in a separate message
    Dispatcher.BeginInvoke((ThreadStart)delegate
    {
        NotifyPropertyChanged("txtContents2");
    });
}
else
{
    this._txtContents2 = value;
    NotifyPropertyChanged("txtContents2");
}

Предполагается, что ваша модель представления имеет доступ к Dispatcher. Пример того, как это сделать, показан в моем сообщении в блоге на базовом классе ViewModel.

1
Tim Cooper 27 Сен 2011 в 20:44
Я просто пробовал это, но почему-то работает с BeginInvoke, а с Invoke - нет ...
 – 
Enriquev
31 Мар 2010 в 22:47
Извините, я имел в виду BeginInvoke - отредактировано. Я думаю, что Invoke будет работать, только если вы установите для DispatcherPriority значение ниже, чем DataBind.
 – 
Kent Boogaart
31 Мар 2010 в 23:48

У меня была аналогичная проблема ранее, здесь

В вашем пользовательском элементе управления обновите привязку и установите для UpdateSourceTrigger значение Explicit

<TextBox Margin="74,145,106,132" x:Name="txtContents2" TextChanged="txtContents2_TextChanged"

Text = "{Путь привязки = txtContents2, UpdateSourceTrigger = Explicit, Mode = TwoWay}" />

Затем в обработчике событий TextChanged обновите привязку вручную, проверив ввод. переместить логику проверки из установщика свойства txtContent2 в bloc999Data в этом обработчике событий

    private void txtContents2_TextChanged(object sender, TextChangedEventArgs e)
    {
        if (int.Parse(txtContents2.Text) > int.Parse(mainBlock.txtContents))
        {
            mainBlock.txtContents2 = "000";
            txtContents2.GetBindingExpression(TextBox.TextProperty).UpdateTarget();
        }
        else
        {
            mainBlock.txtContents2 = txtContents2.Text;
            txtContents2.GetBindingExpression(TextBox.TextProperty).UpdateSource();
        }
    }

И это работает.

Надеюсь, это поможет!!

0
Community 23 Май 2017 в 15:26
1
Это работает, но мне действительно нужен мой код, чтобы оставаться внутри моего класса, и из него у меня нет доступа к моему TextBox, поэтому я не могу его обновить.
 – 
Enriquev
31 Мар 2010 в 22:46