Winforms для преобразования WPF: BeginInvoke к чему?
Вот мой старый код из WinForms:
private void ValueChanged(double inValue1, double inValue2) {
//only manual mode for this driver, so that easy.
if (ValueLabel.InvokeRequired) {
ValueLabel.Invoke(new MethodInvoker(delegate {
ValueLabel.Text = (inValue1* inValue2/ 1000).ToString("f1");
}
));
}
else {
ValueLabel.Text = (inValue1* inValue2/ 1000).ToString("f1");
}
}
Есть ли простой способ конвертировать это в WPF? До сих пор у меня было:
private void KVPValueChanged(double inValue1, double inValue2) {
if (ValueLabel.Dispatcher.Thread == Thread.CurrentThread){
ValueLabel.Content = (inValue1* inValue2/ 1000).ToString("f1");
} else {
ValueLabel.Dispatcher.BeginInvoke(delegate {
ValueLabel.Content = (inValue1* inValue2/ 1000).ToString("f1");
});
}
}
Но второй вызов делегата не работает. Как я могу вызвать этот делегат? Я предполагаю, что могу пройти через весь метод делегата, создать экземпляр метода делегата, вызвать этот конкретный экземпляр и т.д., Но я думал, что все эти анонимные делегаты должны избегать этой проблемы. Кроме того, мой старый код winforms имеет эту первую реализацию повсюду, поэтому мне бы очень хотелось избежать де-анонимизации всех моих делегатов.
Изменить: Я могу попытаться использовать MethodInvoker, как раньше, но тогда компилятор запутался. MethodInvoker является частью System.Windows.Forms, поэтому использование этого подхода не работает. Как в:
private void ValueChanged(double inValue1, double inValue2) {
if (ValueLabel.Dispatcher.Thread == Thread.CurrentThread) {
ValueLabel.Content = (inValue1* inValue2/ 1000).ToString("f1");
}
else {
ValueLabel.Dispatcher.BeginInvoke(new System.Windows.Forms.MethodInvoker(delegate {
ValueLabel.Content = (inValue1* inValue2/ 1000).ToString("f1");
}));
}
}
Это использование MethodInvoker не кошерное. Есть ли отдельная реализация или какой-либо другой способ использования такого же поведения?
Ответы
Ответ 1
Мне кажется, вам нужно изменить подпись делегата:
ValueLabel.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate(invalue1, invalue2){
ValueLabel.Content = ...
Кроме того, посмотрите, используя компонент BackgroundWorker. Не только для wpf, но и для асинхронных операций winform.
Ответ 2
System.Windows.Forms.MethodInvoker - это просто делегат, который не принимает параметров и возвращает void. В WPF вы можете просто заменить его System.Action. Существуют и другие встроенные делегаты, которые принимают параметры, возвращают значения или и.
В вашем случае
ValueLabel.Dispatcher.BeginInvoke(new System.Windows.Forms.MethodInvoker(delegate {
ValueLabel.Content = (inValue1* inValue2/ 1000).ToString("f1");
}));
становится
ValueLabel.Dispatcher.BeginInvoke(new Action(delegate() {
ValueLabel.Content = (inValue1* inValue2/ 1000).ToString("f1");
}));