изменить поле _dispatcher в DispatcherObject путем отражения, чтобы изменить свойства объекта DispatcherObject в разных потоках? - PullRequest
0 голосов
/ 24 марта 2019

Можно ли изменить поле _dispatcher в DispatcherObject путем отражения, чтобы изменить свойства объекта DispatcherObject в потоках?

Я новичок в разработке wpf. Наблюдая за исходным кодом DispatcherObject, я понимаю, что объект DispatcherObject может быть доступен только его ассоциированному Dispatcher. Могу ли я изменить разрешение доступа в случае перекрестной многопоточности, изменив поле _dispatcher, чтобы текущий поток мог работать правильно? DispatcherObject, эта проблема беспокоила меня давно.

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            Thread threadOri = Thread.CurrentThread;

            Thread thread = new Thread(() =>
            {
                FieldInfo field = typeof(DispatcherObject).GetField("_dispatcher", BindingFlags.NonPublic | BindingFlags.Instance);
                DispatcherObject obj = new UIElement();

                field.SetValue(btn, obj.Dispatcher);

                try
                {
                    btn.Width = 100;
                }
                catch
                { }

                try
                {
                    btn.Height = 100;
                }
                catch
                { }

                try
                {

                    //There is an error here
                    TextBox tbx = new TextBox();
                    field.SetValue(tbx, Dispatcher.FromThread(threadOri));
                    btn.Content = tbx;

                }
                catch
                { }


                field.SetValue(btn, Dispatcher);
            });

            thread.TrySetApartmentState(ApartmentState.STA);

            thread.Start();
            thread.Join();

            //Why is there no automatic redraw?
            btn.Visibility = Visibility.Collapsed;
            btn.Visibility = Visibility.Visible;
        }
    }

1 Ответ

1 голос
/ 24 марта 2019

Изменение свойства Dispatcher одного элемента пользовательского интерфейса в визуальном дереве не имеет смысла, поскольку все элементы в дереве должны иметь одинаковое сродство к потоку.

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

btn.Dispatcher.Invoke(() =>
{
    btn.Content = new TextBlock { Text = "Click Me!" };
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...