Пользовательские ContextMenu TextBox в стиле, ошибка многопоточности - PullRequest
5 голосов
/ 29 октября 2010

В приложении WPF я использую Textbox с пользовательским стилем, в котором ContextMenu переопределяется следующим образом:

  <Style TargetType="{x:Type TextBox}">
    <Setter Property="ContextMenu">
      <ContextMenu>
        <MenuItem Header="Copy"/>
      </ContextMenu>
    </Setter>
  </Style>

Это будет работать до тех пор, пока я не запущу окно с TextBox в разных потоках, таких как:

Thread thread = new Thread(()=>
                                {
                                TestWindow wnd = new TestWindow();
                                wnd.ShowDialog();
                                });
thread.SetApartmentState(ApartmentState.STA);
thread.IsBackground = true;
thread.Start();

Но это вызывает InvalidOperationException «Вызывающий поток не может получить доступ к этому объекту, поскольку другой поток владеет им.».

Как избежать этой проблемы?

Ответы [ 2 ]

5 голосов
/ 01 ноября 2010

Проблема заключается в том, что ваш стиль повторно используется как оптимизация, поэтому ContextMenu используется повторно - это стандарт и хорошо работает для однопоточных, но не для многопоточности.

Я бы попытался переместить стиль в ресурсный словарь и сослаться на него как на StaticResource. Затем я бы пометил: х: Общий = «ложь» Это будет создавать новый экземпляр при каждом доступе к ресурсу - я не уверен, что он работает для стиля «поймать все» без стиля, который у вас есть. Затем вы можете сделать контекстное меню ресурсом и ссылаться на него как на StaticResource - это должно быть сделано.

0 голосов
/ 01 ноября 2010

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

Вы должны быть уверены, что находитесь в потоке пользовательского интерфейса при применении обновлений пользовательского интерфейса. Вы можете проверить, требуется ли это, проверив значение object.InvokeRequired. При необходимости вы можете вызвать метод, вызвав object.Invoke([delegate]).

Помимо этого вы также можете использовать диспетчер, см. MSDN и в этом блоге . Приятного чтения

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