Binding и appendText приводят к текстовому полю. Общий начальный в WPF. Нужна помощь - PullRequest
3 голосов
/ 14 февраля 2010

Тотальный новичок в WPF, так что терпите меня.

Прежде чем приступить к работе, я строю приложение для проверки концепции. Я решил попробовать WPF.

Это сценарий:

У меня есть:

  • a View = CustomerView (userControl с кнопкой «Купить продукты»)
  • текстовое поле (добавить все действия, которые происходят)
  • ViewModel = CustomerViewModel (общается со службой и т. Д. И получает результаты
  • Модель = Клиент (простой класс со свойствами со встроенным InotifyPropertyChanged

Учитывая, что у меня есть коллекция продуктов, и для каждого продукта, который я покупаю, мне нужно ПРИЛОЖИТЬ ТЕКСТ К TXTBox в userControl, распечатывая все происходящие действия, textBox должен выглядеть как

Start buying .....
Product 1 Sold
Product 2 Sold
Fineshed....

Моя проблема в том, что, несмотря на то, что я успешно уведомляю после продажи каждого предмета, я не могу понять, как я могу связать или сделать "Товар 1 продан, товар 2 появляется в текстовом поле.

В окнах форм у меня будет userControl со свойством ProductStatus и всякий раз, когда я получаю уведомление, я добавляю текст в textBox. «Я помещаю beginInvoke, когда получаю операцию threadCross» при входе из службы. Это еще одна проблема, которую мне придется исследовать

private ProductStatus _productStatus;
public ProductStatus Status
{
  get { return _productStatus; }
  set
  {
    _printStatus = value;                 
    BeginInvoke((MethodInvoker)(() => txtProductResult.AppendText(string.Format("Product Sold {0}", Environment.NewLine))));  
  }
}

Как добавить текст в myTextBox для каждого предмета, который я продаю?

================= Добавлен текущий код =========================== ====

    void LogChanged(object sender, NotifyCollectionChangedEventArgs e) 
        { 
            foreach(object item in e.NewItems) 
            { 
                txtProduct.AppendText(item.ToString()); 
            } 
        } 

         <TextBox Margin="12,41,12,59" Name="txtPrintResult" />
       <TextBox Text="{Binding TicketPrintLog, Mode=OneWay}" Margin="12,41,12,12" />


            ProductModel
            =============
             public string ProductLog{ get; set; }


            ProductViewModel
            ==================
            public string ProductLog
            {
                get { return _ProductModel.ProductLog; }
            }   
            internal void AppendToProductLogText(string text)
            {
                _ProductModel.ProductLog += text + Environment.NewLine;
                OnPropertyChanged("ProductLog");
            } 

            void ProductSoldNotificationReceived(object sender, notificationEventArgs e)
            {
                //THIS FIRES WHENEVER I PRODUCT IS SOLD.
                AppendToProductLogText(e.Message);
             }

            ProductView (userControl) XAML
            ================================
            <TextBox Margin="12,41,12,59" Name="txtResult" Text="{Binding ProductLog, Mode=OneWay}" />  

            IN CODE BEHIND I DO

              public void Action1()
              {
                txtResult.AppendText(_productViewModel.ProductLog);
              }
               public void SellProductAction()
              {
                txtResult.AppendText(_productViewModel.ProductLog);
              }

У меня проблема в том, что мне все еще нужно это сделать

        txtResult.AppendText(_productViewModel.ProductLog); 

, который лишает смысла привязку данных и при выполнении действия SellproductAction. Я получаю уведомление только о последнем товаре, он не добавляет проданный Product1, проданный Product 2 и т. Д.

Любые идеи

Ответы [ 2 ]

6 голосов
/ 14 февраля 2010

Во-первых, вы все равно можете сделать это способом Windows Forms, добавив новый текст к существующему тексту:

txtProductResult = txtProductResult + Environment.NewLine + "Product sold";

(Если вы делаете это из фонового потока, вам нужно будет использовать txtProductResult.Dispatcher.BeginInvoke вместо txtProductResult.BeginInvoke.)

Однако идиоматический способ сделать это в WPF - это привязка данных. Таким образом, вы должны создать свойство ProductSalesLog для вашей модели представления и связать TextBox с этим свойством. Затем при каждом обновлении свойства ProductSalesLog в модели представления TextBox будет обновляться автоматически. Обратите внимание, что ваша модель представления должна реализовывать INotifyPropertyChanged и вызывать событие PropertyChanged для свойства ProductSalesLog. Таким образом:

public class CustomerViewModel : INotifyPropertyChanged
{
  private string _productSalesLog = String.Empty;
  public string ProductSalesLog
  {
    get { return _productSalesLog; }
  }

  internal void AppendSalesLogText(string text)
  {
    _productSalesLog += text + Environment.NewLine;
    OnPropertyChanged("ProductSalesLog");
  }
}

А по вашему мнению:

<TextBox Text="{Binding ProductSalesLog, Mode=OneWay}" />
0 голосов
/ 14 февраля 2010

Поскольку WPF является управляемой данными структурой, у вас должна быть привязка данных вашего вида к свойствам модели и модели вашего представления. Любые изменения в модели или модели представления могут затем быть переданы в представление через интерфейс INotifyPropertyChanged (путем вызова события propertyChanged).

Это означает, что для большинства целей вам не нужно получать доступ к свойствам вашего пользовательского элемента управления. Это должно быть возможно при наличии статуса продукта на вашей модели представления, и ваше текстовое поле должно привязываться к этому свойству. Вам, конечно, нужно будет убедиться, что при вызове метода установки статуса продукта возникает событие PropertyChanged, чтобы уведомить представление об обновлении

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...