【发布时间】:2017-11-07 14:40:38
【问题描述】:
这是我在这里的第一篇文章,所以我希望我做的一切都是正确的。
我正在使用 .NET Framework 4 客户端配置文件。
我想将 .doc 文件中的数据加载到我的程序中并使用这些信息。这可能需要很多时间,因为我需要浏览文档的表格并检查里面的内容。这已经可以了,唯一的问题是屏幕死机了,你看不到是否发生了什么。
我也知道这在 excel 中会更快更容易,但由于这种类型的数据在我们公司一直存储在 word 文档中,所以我必须保持这样。
所以我想做的是计算我必须读取的表中的所有行,将其设置为进度条的最大值,然后在每一行之后我将计算值 + 1。
我的负载 Button 与 Command 绑定到 LoadWordDocCmd 和进度条:
<Button Name="btnLoadFile"
Content="Load" Height="23"
Command="{Binding LoadWordDocCmd}"
HorizontalAlignment="Right" Margin="0,22,129,0"
VerticalAlignment="Top" Width="50"
Visibility="{Binding VisModeAddNew}"
/>
<ProgressBar HorizontalAlignment="Left" Height="24" Margin="574,52,0,0"
VerticalAlignment="Top" Width="306"
Name="prgBarAddNewLoadWord"
Minimum="0"
Maximum="{Binding AddNewProgressBarMaxVal, Mode=OneWay}"
Value="{Binding AddNewProgressBarValue, Mode=OneWay}"
Visibility="{Binding AddNewProgressBarVisible}"/>
这里是RelayCommand:
/// <summary>
/// Relaycommand for Function loadWordDocument
/// </summary>
public RelayCommand LoadWordDocCmd
{
get
{
if (this.m_loadWordDocCmd == null)
{
this.m_loadWordDocCmd = new RelayCommand(this.loadWordDocument, canLoadWordDoc);
}
return m_loadWordDocCmd;
}
private set
{
this.m_loadWordDocCmd = value;
}
}
/// <summary>
/// checks if the Word Document can be loaded
/// </summary>
/// <param name="parameter">not used</param>
/// <returns>if it could Execute, then true, else false</returns>
private bool canLoadWordDoc(object parameter)
{
bool ret = false;
if (this.m_fileSelected)
{
ret = true;
}
return ret;
}
我已经做的是使用BackgroundWorker。
我能够将 Button-Command 绑定到具有 RelayCommand 和 BackgroundWorker 的函数,但后来我无法再检查 canExecute 函数。
我用它来测试进度条,它正在工作:
xaml:
<Button ...
Command="{Binding Path=InstigateWorkCommand}"
/>
cs:
private BackgroundWorker worker;
private ICommand instigateWorkCommand;
public ProggressbarSampleViewModel()
{
this.instigateWorkCommand = new
RelayCommand(o => this.worker.RunWorkerAsync(), o => !this.worker.IsBusy);
this.worker = new BackgroundWorker();
this.worker.DoWork += this.DoWork;
this.worker.ProgressChanged += this.ProgressChanged;
}
public ICommand InstigateWorkCommand
{
get { return this.instigateWorkCommand; }
}
private int _currentProgress;
public int CurrentProgress
{
get { return this._currentProgress; }
private set
{
if (this._currentProgress != value)
{
this._currentProgress = value;
OnPropertyChanged("CurrentProgress");
}
}
}
private void ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.CurrentProgress = e.ProgressPercentage;
}
private void DoWork(object sender, DoWorkEventArgs e)
{
// do time-consuming work here, calling ReportProgress as and when you can
for (int i = 0; i < 100; i++)
{
Thread.Sleep(1000);
_currentProgress = i;
OnPropertyChanged("CurrentProgress");
}
}
但是我怎样才能让它与 canExecute 一起工作?这是我的函数标题:
/// <summary>
/// Function for Load Word Document
/// </summary>
/// <param name="parameter">not used</param>
private void loadWordDocument(object parameter)
这是中继命令类:
public class RelayCommand : ICommand
{
private readonly Action<object> methodToExecute;
private readonly Func<object, bool> canExecute;
public event EventHandler CanExecuteChanged;
public void RaiseCanExecuteChanged()
{
EventHandler handler = CanExecuteChanged;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
public RelayCommand(Action<object> execute)
: this(execute, null) { }
public RelayCommand(Action<object> methodToExecute, Func<object, bool> canExecute)
{
this.methodToExecute = methodToExecute;
this.canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
// wird keine canExecute-Funktion übergeben, so liefert diese
// true zurück, ansonsten wird die custom canExecute-Funktion
// mit den übergebenen Parametern aufgerufen.
return canExecute == null ? true : canExecute.Invoke(parameter);
}
public void Execute(object parameter)
{
methodToExecute(parameter);
}
}
感谢您的帮助,希望我发布的这个问题是正确的!
【问题讨论】:
-
您是否可以选择使用 Task 和 IProgress 而不是 BackgroundWorker?见stackoverflow.com/a/35316334/982149
-
当你想刷新Button的状态时,你应该调用命令的RaiseCanExecuteChanged()方法。什么有效,什么无效……?
-
我什至无法让 RelayCommand 与 canExecuteChange 一起工作。当使用 new RelayCommand(o => this.worker.RunWorkerAsync(), o => !this.worker.IsBusy);我不知道如何让 canLoadDoc 的函数指针工作
-
我从您的问题标题中删除了强制标签。阅读here为什么。另外,我从您的代码示例中删除了空的 doc-cmets,因为它们只会降低代码的可读性。
-
阅读您的问题后,我并不完全清楚您的特殊和孤立问题是什么。处理时 GUI 无响应?按钮的启用状态未更新?
标签: c# wpf xaml mvvm progress-bar