2013-06-02 5 views
0

Здесь я говорю о приложении Windows Forms, написанном на C#. Рассмотрим простую модельКак сделать Microsoft.VisualBasic.PowerPacks.DataRepeater мгновенно обновлять связанные данные?

class Labelled 
{ 
    private string label; 
    public string Label 
    { 
     get { return label; } 
     set 
     { 
      if (label != value) 
      { 
       string message = String.Format(
        "Label changed from {0} to {1}", 
        label, value 
       ); 
       MessageBox.Show(message); 
       label = value; 
      } 
     } 
    } 

    public Labelled(string label) 
    { 
     this.label = label; 
    } 
} 

class Model 
{ 
    public Labelled SingularLabelled { get; set; } 

    public List<Labelled> ListedLabelled { get; set; } 

    public Model() 
    { 
     SingularLabelled = new Labelled("Singular"); 

     ListedLabelled = new List<Labelled>(); 

     for (int i = 1; i <= 10; ++i) 
      ListedLabelled.Add(new Labelled("Listed " + i.ToString())); 
    } 
} 

У нас есть простой класс Labelled с струнной свойством Label и класса Model с членом SingularLabelled типа Labelled и ListedLabelled который представляет собой список из Labelled-х гг.

Теперь я хочу отобразить данные для пользователя. Вот мои настройки:

Main window and data bindings

Главное окно имеет TextBox для отображения SingularLabelled.Label и DataRepeater из Visual Basic PowerPacks для отображения меток элементов ListedLabelled. ItemTemplateDataRepeater состоит всего из одного TextBox.

Давайте сосредоточимся на привязке к одному каналу, а именно, я хочу, чтобы базовые данные обновлялись, когда Пользователь меняет содержимое текстового поля. Свойство LabelLabelled вызывает уведомление в форме окна сообщения, поэтому я могу точно узнать, когда данные обновляются. Теперь стрелки представляют собой привязки. Синие стрелки обозначают источник данных и красные для элементов данных. Создается экземпляр Model и привязан к modelBindingSource в конструкторе формы главного окна.

И здесь мы приходим к очень важному. Я хочу, чтобы данные были обновлены сразу в синхронизации с тем, что пользователь вводит, поэтому я убедился, что режимы обновления источника данных для привязок данных установлены на OnPropertyChanged. Сгенерированный код, который может представлять интерес здесь

this.singularTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.modelBindingSource, "SingularLabelled.Label", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); 
this.listedTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.listedLabelledBindingSource, "Label", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); 

И это работает, как ожидается, при вводе текста в текстовое поле SingularLabelled но текстовые поля в DataRepeater триггером только тогда, когда они теряют фокус обновления. Я хочу, чтобы они вели себя как единичные. Идеальное решение было бы сделать это с помощью дизайнера. Кто-нибудь знает как это сделать?

SingularLabelled label update

ListedLabelled label update

Выше приведен пример программы работы. Обратите внимание, что метка SingularLabelled обновляется каждый введенный символ, а члены ListedLabelled получают весь отредактированный фрагмент, обновленный после того, как соответствующее текстовое поле теряет фокус.

ответ

1

Мы смогли преодолеть это ограничение DataRepeater, моделируя клавишу Tab.

private void listedTextBox_TextChanged(object sender, EventArgs e) 
    { 
     //simulate tab key to force databinding 
     SendKeys.Send("{TAB}"); 
     SendKeys.Send("+{TAB}"); 
    } 
+0

Это интересное предложение. Тем не менее на данный момент я просто сбросил DataRepeater и собрал свой собственный элемент управления, подобный ему, который не имеет этой проблемы. –