我有一個ObservableCollection<Conversion>佇列,系結到ListBox控制ItemTemplate包含 aTextBlock和 a Button。單擊該按鈕時,將啟動 Win32 行程。此行程有一個ErrorDataReceived事件處理程式方法,它讀取行程輸出并應該更新Conversion集合中物件的 PercentComplete 屬性。PercentComplete 系結到TextBlock的 Text 屬性。
如何從 Win32 行程事件更新 PercentComplete?我希望將Conversion物件傳遞給ErrorDataReceived事件處理程式,但DataReceivedEventArgs只有一個字串型別的 Data 屬性。
這是代碼:
XAML:
<ListBox ItemsSource="{Binding Queue}" SelectedItem="{Binding SelectedItem}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding PercentComplete}" />
<Button Command="convertor:Commands.RunConversion">Run</Button>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
代碼隱藏:
private ObservableCollection<Conversion> _queue;
public ObservableCollection<Conversion> Queue
{
get { return _queue; }
set
{
_queue = value;
RaisePropertyChange("Queue");
}
}
private Conversion _selectedItem;
public Conversion SelectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
RaisePropertyChange("SelectedItem");
}
}
private void RunConversion_Executed(object sender, ExecutedRoutedEventArgs e)
{
...
using (var ffmpeg = new Process())
{
...
ffmpeg.EnableRaisingEvents = true;
ffmpeg.ErrorDataReceived = FfmpegProcess_ErrorDataReceived;
// I realize it is weird I am working with ErrorDataReceived instead
// of OutputDataReceived event, but that's how ffmpeg.exe rolls.
ffmpeg.Start();
ffmpeg.BeginErrorReadLine();
}
}
private void FfmpegProcess_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
var processOutput = e.Data;
var percentComplete = ParsePercentComplete(processOutput);
//TODO Pass percentComplete to Conversion.PercentComplete!?
}
班級:
public class Conversion : INotifyPropertyChanged
{
private double _percentComplete;
public double PercentComplete
{
get { return _percentComplete; }
set
{
_percentComplete = value;
RaisePropertyChange("PercentComplete");
}
}
public void RaisePropertyChange(string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
uj5u.com熱心網友回復:
好的,我解決了。解決方案的關鍵是process.Id它提供了對特定于ObservableCollection專案的程序的參考。
具體來說,我擴展了Conversionwith ProcessProcess 屬性以存盤該特定行程的資訊,然后我可以在集合中找到該專案并從行程事件處理程式中的行程輸出更新其屬性。
這是更新后的代碼:
代碼隱藏:
private ObservableCollection<Conversion> _queue;
public ObservableCollection<Conversion> Queue
{
get { return _queue; }
set
{
_queue = value;
RaisePropertyChange("Queue");
}
}
private Conversion _selectedItem;
public Conversion SelectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
RaisePropertyChange("SelectedItem");
}
}
private void RunConversion_Executed(object sender, ExecutedRoutedEventArgs e)
{
...
var ffmpeg = new Process();
ffmpeg.EnableRaisingEvents = true;
ffmpeg.ErrorDataReceived = FfmpegProcess_ErrorDataReceived;
ffmpeg.Start();
conversion.Process = ffmpeg; // This is new
ffmpeg.BeginErrorReadLine();
}
private void FfmpegProcess_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
var processOutput = e.Data;
var percentComplete = ParsePercentComplete(processOutput);
var processId = (sender as Process).Id; // These three lines are new
var conversion = Queue.Where(c => c.Process.Id == processId).FirstOrDefault();
conversion.PercentComplete = percentComplete; // WTF!!!!
}
班級
public class Conversion : INotifyPropertyChanged
{
private double _percentComplete;
public double PercentComplete
{
get { return _percentComplete; }
set
{
_percentComplete = value;
RaisePropertyChange("PercentComplete");
}
}
// New property
private Process _process;
public Process Process
{
get { return _process; }
set
{
_process= value;
RaisePropertyChange("Process");
}
}
public void RaisePropertyChange(string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/399812.html
