I open the window through the stream as follows.

Thread thread = new Thread(() => { AskReplace ask = new AskReplace(to); ask.Show(); Dispatcher.Run(); }); thread.SetApartmentState(ApartmentState.STA); thread.IsBackground = true; thread.Start(); 

Where AskReplace is the name of the window.

 public AskReplace(string userFileToReplace) { InitializeComponent(); FileToReplace = userFileToReplace; ViewNameOfFile ="File "+userFileToReplace+"is exist do you want to replace it"; PropertyChanged +=OnPropertyChanged; } 

I sign the OnPropertyChanged method on the PropertyChanged event. The method itself looks like this.

 private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) { FileText.Text = ViewNameOfFile; } 

Where FileText TextBlock looks like this.

  <TextBlock Foreground="White" Margin="0,144,0,63" HorizontalAlignment="Center" Text="{Binding viewNameOfFile}" VerticalAlignment="Center" x:Name="FileText"/> 

and the ViewNameOfFile property of type string, which looks like this.

 private string viewNameofFile; public string ViewNameOfFile { get { return viewNameofFile; } set { viewNameofFile = value; RunProperty("ViewNameOfFile"); } } 

PropertyChanged property I run through the RunProperty method, the method looks like this.

 private void RunProperty(string propertyName) { //PropertyChanged +=OnPropertyChanged; если я подпишу метод OnPropertyChanged здесь то всё нормально.Я конечно могу так сделать,но мне бы хотелось бы знать с чем это может быть связано. var handler = PropertyChanged;//в этом месте почему-то PropertyChanged равен нулю хотя я его проинициализировал в конструкторе.Подписав на него метод OnPropertyChanged. if (handler!=null) handler.Invoke(this, new PropertyChangedEventArgs(propertyName)); } 

I suspect that this is somehow related to Dispatcher.Run () but not sure about that.

  • And what is the purpose of these frauds? - Arheus 2:55 pm
  • I create an application that sorts the music by tag, I start processing files through a separate stream using the BackgroundWorker class so that several processing can be done at the same time. As I plan to rewrite it in the future under the Web. which works in MTA mode. And the flow that opens a new window should be STA, I open the AskReplace window, through a new flow, pre-setting ApartmentState to STA. If I understood your question correctly. - Faradey Inimicos
  • How exactly is PropertyChanged declared and how exactly do you initialize it in the constructor? - PashaPash
  • public event PropertyChangedEventHandler PropertyChanged; it is declared in the body of the class, and the method is signed when the constructor is called. - Faradey Inimicos
  • Binding viewNameOfFile , by the way, is wrong, it is necessary to be attached to the property, and not to the field. - VladD

1 answer 1

If there are no special outlets, I recommend using Task and async / await. BackgroundWorkers were still under winforms and were somewhat outdated. The code will be easier and clearer. As for the window, that would put the apartment flow, it looks strange, because This can be done without a window:

 Thread thread = new Thread(MethodWhichRequiresSTA); thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA thread.Start(); thread.Join(); //Wait for the thread to end 

And I wonder, why, actually STA. Usually, processing in the background is performed, and notification of the execution and other things already in the UI stream. For example:

  /// <summary> /// Контекст асинхронной обработки Таска. Если нужны параметры — добавляй их в конструктор. /// </summary> public class BackgroundWorkerAsyncContext : IDisposable { #region Public Methods public Task<object> ProccessTrack() { var task = new Task<object>(() => { //тут должна быть обработка какая-то. DateTime a = DateTime.Now; Thread.Sleep(1000); Console.WriteLine((DateTime.Now - a).TotalMilliseconds); return new object(); }); task.Start(); return task; } public void Dispose() { } #endregion Public Methods } /// <summary> /// ViewModel нашего трека. Имеет имя, флаг того, что трек сейчас в обработке и соманду обработки. /// </summary> public class TrackViewModel : ViewModelBase { #region Private Fields private RelayCommand _compressCommand; private bool _isInProcess; private string _name; #endregion Private Fields #region Public Properties public ICommand CompressCommand { get { return _compressCommand ?? (_compressCommand = new RelayCommand(async () => { try { //выставяем флаг обработки IsInProcess = true; //сама обработка using (var context = new BackgroundWorkerAsyncContext()) { var result = await context.ProccessTrack(); //result - выхлоп от таска, в данном примере object. } } catch (Exception) { //что то с исключением сделать. } finally { //убираем флаг. IsInProcess = false; } })); } } public bool IsInProcess { get { return _isInProcess; } set { if (value != _isInProcess) { _isInProcess = value; RaisePropertyChanged(); } } } public string Name { get { return _name; } set { if (value != _name) { _name = value; RaisePropertyChanged(); } } } #endregion Public Properties }