Обработка внутренних событий в классе пользовательского интерфейса - PullRequest
0 голосов
/ 10 февраля 2020

РЕДАКТИРОВАТЬ: я обновил это с двумя рекомендуемыми методами

Я пишу простой пользовательский просмотрщик данных PI ( OSISoft ). У меня есть два класса, один для пользовательского интерфейса и один для взаимодействия с сервером PI / логин программы c. Свойство для отображаемых данных имеет событие, которое срабатывает при изменении свойства. Как заставить это изменение распространиться на класс пользовательского интерфейса, чтобы соответствующее текстовое поле автоматически обновляло sh?

Исходный код:

namespace PIViewer {
    public partial class MainWindow : Window
    {
        ProgLogic logic;

        public MainWindow() {
            InitializeComponent();
            logic = new ProgLogic();
            InitializeValues();
        }

        private void InitializeValues() {
            logic.SomeValue = logic.GetValFromServer(valueTag);
        }

        private void TextBoxSomeValue(object sender, TextChangedEventArgs e) {
            //  ??? something happens here?
        }
    }

    public class ProgLogic {
        private int someValue;

        public event System.EventHandler SomeValueChanged;

        protected void OnSomeValueChanged()
        {
            SomeValueChanged?.Invoke(this, EventHandlerArgs e);
        }

        public int SomeValue {
            get => someValue;
            set {
                someValue = value;
                OnSomeValueChanged();
            }
        }

        public int GetValFromServer(string valueTag) {
            int piValue;
            piValue = PISDKMethodToGetServerValue(valueTag);
            return piValue;
        }
    }
}

Метод 1: События

namespace PIViewer {
    public partial class MainWindow : Window
    {
        ProgLogic logic;

        public MainWindow() {
            InitializeComponent();
            logic = new ProgLogic();
            logic.SomeValueChanged += Logic_SomeValueChanged;
            InitializeValues();
        }

        private void Logic_SomeValueChanged(int obj) {
            TextBoxSomeValue.Text = obj.toString();
        }

        private void InitializeValues() {
            logic.SomeValue = logic.GetValFromServer(valueTag);
        }

        private void TextBoxSomeValue_TextChanged(object sender, TextChangedEventArgs e) {

        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
            logic.SomeValueChanged -= Logic_SomeValueChanged;
        }

    }

    public class ProgLogic {
        private int someValue;

        public event Action<int> SomeValueChanged;

        public virtual void OnSomeValueChanged(int newValue) {
            SomeValueChanged?.Invoke(newValue);
        }

        public int SomeValue {
            get => someValue;
            set {
                someValue = value;
                OnSomeValueChanged(value);
            }
        }

        public int GetValFromServer(string valueTag) {
            int piValue;
            piValue = PISDKMethodToGetServerValue(valueTag);
            return piValue;
        }
    }
}

Метод 2: шаблон MVVM

MainWindow.xaml:

<Window
    Closing="Window_Closing"
    Title="My App">
    <TextBox x:name="TextBoxSomeValue" text="{binding SomeValue, UpdateSourceTrigger=PropertyChanged}" />
</Window>

Важной частью здесь является параметр binding в текстовом поле Определение TextBox, которое указывает на PropertyChangedEventHandler.

C# код:

namespace PIViewer {
    public partial class MainWindow : Window
    {
        ProgLogic logic;

        public MainWindow() {
            InitializeComponent();
            logic = new ProgLogic();
            InitializeValues();
        }

        private void InitializeValues() {
            logic.SomeValue = logic.GetValFromServer(valueTag);
        }

        private void TextBoxSomeValue_TextChanged(object sender, TextChangedEventArgs e) {
            //  run some other code when the text box updates
        }
    }

    public class ProgLogic : INotifyPropertyChanged {
        private int someValue;

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChange(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public int SomeValue {
            get => someValue;
            set {
                someValue = value;
                OnPropertyChange("SomeValue")
            }
        }

        public int GetValFromServer(string valueTag) {
            int piValue;
            piValue = PISDKMethodToGetServerValue(valueTag);
            return piValue;
        }
    }
}

ProgLogi c теперь реализует INotifyPropertyChanged, который уведомляет представление об изменениях свойств, так что привязки обновляются .

Ответы [ 2 ]

1 голос
/ 10 февраля 2020

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

  1. В верхней части вашего visual2019, в опциях меню. откройте меню отладки и внизу вы увидите («Имя вашего проекта» + свойства)

2. Вы попадете в новое окно с опциями меню слева, go для настройки.

3.Создайте строку и установите значение «Некоторый случайный текст»

Примечание: В примере я поместил одно текстовое поле перед другим, хотя это не отличный метод, он предотвратит появление текста в виде двойного символа или пустого символа

Пример строки настроек

    xaml
    <Window x:Class="SaveNewText.MainWindow"                
       Title="MainWindow" Height="450" Width="800">
        <Grid>
           <TextBox x:Name="DefaultText" Height="250" Width="250" 
           Background="Transparent" 
           Foreground="Black" MouseDown="TextBlock_MouseDown" IsReadOnly="True"/>
           <TextBox x:Name="NewText" Height="250" Width="250" Background="Transparent" 
           Foreground="Black" TextChanged="NewText_TextChanged"/>
        </Grid>
    </Window>

    xaml.cs
    namespace SaveNewText
    {   
      public partial class MainWindow : Window
      {
         public MainWindow()
         {
            InitializeComponent();
            DefaultText.Text = Properties.Settings.Default.TextString;
         }
         private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
         {
           NewText.Focus();
         } 
         private void NewText_TextChanged(object sender, TextChangedEventArgs e)
         {
             Properties.Settings.Default.TextString = NewText.Text;
             Properties.Settings.Default.Save();
             DefaultText.Text = Properties.Settings.Default.TextString;
         }
     }
   }
1 голос
/ 10 февраля 2020

Я вижу, вы движетесь в правильном направлении с C# системой событий. Одна вещь, которую я бы изменил, это тип события с System.EventHandler на System.Action<int>. Несмотря на то, что люди склонны распространять расширяющий класс System.EventArgs и писать собственные делегаты для обработки событий, использование System.Action<T> намного проще, чем gr asp для новичка.

Так что давайте go на примере System.Action<int> сейчас же. Во-первых, давайте изменим класс ProgLogic, чтобы он выглядел так:

public class ProgLogic
{
    public event Action<int> SomeValueChanged;

    //
    // your other code goes here
    //

    private void OnSomeValueChanged(int newValue)
    {
        SomeValueChanged?.Invoke(newValue);
    }
}

Теперь вам нужно подписаться на ранее записанное событие в классе MainWindow. Поэтому мы делаем это как можно раньше - в конструкторе MainWindow:

public MainWindow()
{
    InitializeComponent();
    logic = new ProgLogic();
    logic.SomeValueChanged += OnSomeValueChanged;
    InitializeValues();
}

Затем вы описываете свои логики c в методе обратного вызова OnSomeValueChanged, например:

private void OnSomeValueChanged(int newValue)
{
    TextBoxSomeValue.text = newValue.ToString();
}

Убедитесь, что вы отменили подписку на событие, когда MainWindow уничтожается, чтобы предотвратить утечку памяти. Это просто скелет для всей логики c. Я оставил место для интерпретации. ;)

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