【发布时间】:2015-11-13 03:43:29
【问题描述】:
是的,我知道这在 WPF 中会更容易实现。我经常听到。可悲的是,这是不可能的。
我正在编写一个 WinForms 应用程序,我需要“淡入”和“淡出”一个控件。透明度在 WinForms 中几乎是不可能的,所以我尝试使用不透明度:这个想法是在一段时间内更改每个子控件的 ForeColor 属性的 Alpha 通道。这似乎是处理我的 Reactive Extensions 的最佳时机!
我可能的解决方案是:
private void FadeOut()
{
// our list of values for the alpha channel (255 to 0)
var range = Enumerable.Range(0,256).Reverse().ToList();
// how long between each setting of the alpha (huge value for example only)
var delay = Timespan.FromSeconds(0.5);
// our "trigger" sequence, every half second
Observable.Interval(delay)
// paired with the values from the range - we just keep the range
.Zip(range, (lhs, rhs) => rhs)
// make OnNext changes on the UI thread
.ObserveOn(SynchronizationContext.Current)
// do this every time a value is rec'd from the sequence
.Subscribe(
// set the alpha value
onNext:ChangeAlphaValues,
// when we're done, really hide the control
onCompleted: () => Visible = false,
// good citizenry
onError: FailGracefully);
}
// no need to iterate the controls more than once - store them here
private IEnumerable<Control> _controls;
private void ChangeAlphaValues(int alpha)
{
// get all the controls (via an extension method)
var controls = _controls ?? this.GetAllChildControls(typeof (Control));
// iterate all controls and change the alpha
foreach (var control in controls)
control.ForeColor = Color.FromArgb(alpha, control.ForeColor);
}
...这看起来令人印象深刻,但它不起作用。真正令人印象深刻的部分是它不能以两种方式工作!如果我继续这样做,我的下一次绩效评估将获得“远超”。 :-)
- (实际上并不是问题的 Rx 部分)alpha 值实际上似乎没有任何区别。尽管设置了这些值,但显示看起来是一样的。
- 如果我在序列完成之前关闭窗口,我会收到以下错误:
System.InvalidOperationException 未处理 消息:System.Reactive.Core.dll 中出现“System.InvalidOperationException”类型的未处理异常 附加信息:在创建窗口句柄之前,不能对控件调用 Invoke 或 BeginInvoke。
我认为这是取消令牌派上用场的地方 - 但我不知道如何实现它。
我需要以下方面的指导:
如果序列仍在运行,如何优雅地关闭窗口(即不抛出错误),以及如何让颜色的 alpha 值在更改后真正显示。
...或者这可能是完全错误的方法。
我愿意接受其他建议。
【问题讨论】:
-
I am writing a WinForms app, and I need to "fade" a Control in & out- 使用 WPF。 winforms 不支持动画。您可以在 WPF 中使用一行 XAML 实现此目的。 -
Sadly, It is not possible- 然后忘记尝试在 winforms 上引入动画或任何其他丰富的 UI 功能。花时间创建战舰灰色、无聊的 UI,这就是 winforms 的意义所在。 -
所以,您还没有完全接受其他建议。 ;) 我很好奇为什么这是不可能的。您可以使用
ElementHost将 WPF 控件放入 WinForms。这对你来说可能吗? -
你试过检查
Control.IsHandleCreated && ! Control.IsDisposed吗? -
@HighCore
which is what winforms is about... 叹息。是的,我知道。别再戳熊了。 ;-)
标签: c# winforms system.reactive opacity