2012-03-17 3 views
0

Я создаю приложение, которое использует несколько потоков, в результате я хочу попытаться использовать UIControls в моем коде по возможности как можно меньше. То, как я это делаю, - привязать элементы управления к свойству в моем коде за этим способом, я смогу обновить элемент управления, изменив это свойство, и не имеет значения, обновлено ли это свойство в другом потоке. В любом случае я создаю следующий код, чтобы класс создал привязки.Управление привязкой к свойствам не работает

public static class MyExtensionMethods 
{ 

    public static TextBoxBind<T> BindTextBox<T>(this TextBox textbox, string property=null) 
    { 
     return new TextBoxBind<T>(textbox,property); 
    } 
} 



public class TextBoxBind<T> : INotifyPropertyChanged 
{ 
    string property; 

    protected T _Value; 
    public T Value 
    { 
     get { return _Value; } 
     set { _Value = value; OnPropertyChanged(property); } 
    } 

    public event PropertyChangedEventHandler PropertyChanged = delegate { }; 
    protected void OnPropertyChanged(string propertyName){ 
     PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    public TextBoxBind(TextBox textbox, string property) 
    { 
     if (property == null) 
     { 
      property = "Value"; 
     } 
     this.property = property; 

     Binding b = new Binding(property) 
     { 
      Source = this 
     }; 

     b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; 
     textbox.SetBinding(TextBox.TextProperty, b); 
    } 
} 

И на моем XAML у меня есть:

<TextBox Name="textBox2" /> 

Поэтому я буду иметь возможность использовать первый код, который я написал, как:

 var newTextBox2 = textBox2.BindTextBox<int>(); 
     newTextBox2.Value = 50; // this will update the textBox2.Text = "2" 
     // also every time I update the value of textBox2 newTextBox2.Value will update as well 

Проблема заключается в том, когда я пытаюсь привяжите его к пользовательскому объекту. Возьмите этот код, например:

public class Person 
    { 
     public string Name { get; set; } 
     public string Age { get; set; } 

     public override string ToString() 
     { 
      return Age.ToString(); 
     }    

    } 

    void LogIn_Loaded(object sender, RoutedEventArgs e) 
    { 
     txtUsuario.Focus(); 

     var newTextBox2 = textBox2.BindTextBox<Person>("Age"); 

     // here newTextBox2 never updates.... 


    } 

ответ

0

OnPropertyChanged(property); должен указывать на значение, так как это имя вашей собственности. Это не должно указывать на тип T. Так что этот код не является правильным:

if (property == null) 
{ 
    property = "Value"; 
} 

, потому что свойство всегда должно быть "Value"

public T Value  
{  
    get { return _Value; }  
    set { _Value = value; OnPropertyChanged("Value"); }  
} 
1

Когда дело доходит до привязки данных следует обновить объект (не имеет значения CLR свойства или DependencyObject) из той же нити, как интерфейс работает на. Если у вас есть элемент пользовательского интерфейса, связанный с чем-то в коде, обновление из отдельного потока приведет к исключению. Однако вы всегда можете получить поток пользовательского интерфейса и выполнить обновление свойств. Вот кусок кода, который я использую в подобной ситуации, как у вас есть:

ThreadStart updateLogs = delegate() 
{ 
    ObservableCollection<LogMessage> newLogs = this._parcer.Parce(); 
    foreach (LogMessage log in newLogs) 
     LogMessages.Add(log); 
}; 
App.Current.Dispatcher.BeginInvoke(updateLogs, null); 

Этот блок кода выполняется в потоке, отличном от одного UI работает на. Поэтому я извлекаю код, который фактически обновляет источник привязки (который является LogMessages) делегатом updateLogs, а затем запускает этот делегат в потоке пользовательского интерфейса, передавая его диспетчеру приложений.

Тем не менее, приложение WPF может иметь более одного Dispather, если, например, вы создаете отдельные окна в отдельных потоках, хотя этот подход встречается редко. Но на всякий случай класс DependencyObject имеет свойство Dispatcher, в котором ссылается на Dispather, которому принадлежит этот объект.

+0

Я знаю, как использовать dispacher спасибо за помощь. Если вы привяжете свойство к UIcontrol, вы сможете обновить это свойство в отдельном потоке, не получив исключения. Кроме того, вы можете получить подтверждение в UIcontrols ... –

Смежные вопросы