В WPF как обновить основной пользовательский интерфейс в пользовательском элементе управления? - PullRequest
0 голосов
/ 20 апреля 2020

У меня проблема. Я хочу обновить основной пользовательский интерфейс в пользовательском элементе управления. Я пробовал столько раз, но не смог. Тест делится на две категории следующим образом:

Класс 1:

Сначала я назначил элемент управления главного окна (tbInfo, тип TextBlock) напрямую, безуспешно. Поэтому я создал класс textBlockUpdate (реализующий интерфейс уведомления об изменении свойства) и связал его свойства (TextMessage) со свойством Text в tbInfo , безуспешно. Затем я использовал элемент управления контентом, также безуспешно. Код выглядит следующим образом:

     //Feature code in user control.
 info = string.Format("Adding file{0}", System.IO.Path.GetFileName(FileName));
         if (_dataObject.MainWindow != null)
         {
                    _dataObject.MainWindow.ShowInfo(info);
         }


//Feature code in main window.
 public void ShowInfo(string info)
    {
        if (Dispatcher.CheckAccess())
        {
            //tbInfo.Text = info;
            //  textBlockUpdate.TextMessage = info;
            TextBlock textBlock = new TextBlock();
            textBlock.Text = info;
            tbInfoContainer.Content = textBlock;
        }
        else
        {
            Action<string> showInfoDel = (str) =>
            {
                //  tbInfo.Text = info;
                //textBlockUpdate.TextMessage = info;
                TextBlock textBlock = new TextBlock();
                textBlock.Text = info;
                tbInfoContainer.Content = textBlock;
            };
            Dispatcher.BeginInvoke(showInfoDel, info);
        }
    }

Класс 2: Я поместил код в пользовательском элементе управления в поток, или это не удалось. Я попытался три раза, но мне это никогда не удавалось.

1.

 new Thread(()=>{
            this.Dispatcher.Invoke(new Action(()=>{
                //Add the feature code above here
            }));
        }).Start();

2.

Application.Current.Dispatcher.Invoke(new Action(() => {
              //Add the feature code above here
        }));

3.

 Task task = new Task(()=> { 
   //Add the feature code above here
      });
                    task.Start();
                    task.Wait();

Итак, кто-нибудь может сказать мне Как сделать, чтобы это работало?

Ответы [ 2 ]

1 голос
/ 20 апреля 2020

Это не так, как это делается. Также установка свойств класса не называется привязкой. Это простое назначение.

A Binding соединяет два или более (MultiBinding) свойства (цель и источник) и обновляет их автоматически, когда один из два изменения.
Чтобы привязка могла обнаруживать изменения свойств, необходимо реализовать участвующие свойства либо как DependencyProperty (обязательно для цели привязки - предпочтительно для элементов управления), либо позволить им поднять INotifyPropertyChanged.PropertyChanged событие при изменении свойства.

  1. Создание источника данных и привязки

    MainWindow.xaml

    partial class MainWindow : Window
    {
      public static readonly DependencyProperty InfoProperty = DependencyProperty.Register(
        "Info",
        typeof(string),
        typeof(MainWindow),
        new PropertyMetadata(default(string)));
    
      public string Info
      {
        get => (string) GetValue(MainWindow.InfoProperty);
        set => SetValue(MainWindow.InfoProperty, value);
      }
    
      // Update the TextBlock via data binding
      public void ShowInfo(string info)
      {
        this.Info = info;
      }
    }
    
  2. Создание пользовательского интерфейса и настройка привязки данных

    MainWindow.xaml

    <Window>
      <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=MainWindow}, 
                                Path=Info}" />
    </Window>
    

См. Документы Microsoft:

Обзор привязки данных в WPF

Как: реализовать свойство зависимостей

0 голосов
/ 23 апреля 2020

Я нашел решение. Просто перейдите на следующий метод.

 //Call the render thread update UI from the current thread
                    int i = 1;
                    while (i < 10)
                    {
                        if (_dataObject.MainWindow != null)
                        {
                            _dataObject.MainWindow.ShowInfo(info);
                        }
                        Dispatcher.Invoke(new Action(() =>
                        {
                        }), System.Windows.Threading.DispatcherPriority.Background);
                       // Thread.Sleep(100);
                        i++;
                    }
                    //this is a time-consuming process.
                    accessObj.AddFile(_dataObject.Path, fileInfo, fileContent);
                    //Call the render thread update UI from the current thread
                    int j = 1;
                    while (j < 10)
                    {
                        if (j == 1) {
                            _dataObject.AttachFiles.Add(fileInfo);
                        }
                        Dispatcher.Invoke(new Action(() =>
                        {
                        }), System.Windows.Threading.DispatcherPriority.Background);
                        //Thread.Sleep(100);
                        j++;
                    }              
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...