-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WinForms Designer breaks when child control uses WhenActivated #1016
Comments
There are two problems working in tandem to create this experience:
If we decide that If we decide that |
@kentcb thanks for looking into this as well - I didn't anticipate an easy solution for this 😢 |
Hmm, in attempting to solve a different issue, I may have found a reasonable workaround for this problem too. I wanted to define base classes for public class MainFormDesignable : ReactiveForm<MainViewModel>
{
}
public class MainForm : MainFormDesignable
{
public MainForm()
{
this.WhenActivated(...);
}
} As a consequence of this, the designer does not execute the I can't even the Winforms designer, but this does appear to work. You can find my repro at https://github.com/kentcb/winforms-rxui-repro. |
This is a age old and "well known" bug in WinForms. I would recommend working around it by adding static property "IsRunning" in Program class (default value false), setting it to true in Main() method before entering Run loop and then checking that static property instead of broken designer property. Of course many similar solutions can be devised... |
@goliat43 so this is something that needs to be fixed in the application, rather than something we can address in ReactiveUI? 😢 |
Ah. Perhaps a bit too quick to post. I read this report as a "my app isn't working" and just pointed out the quickest route to fix it. Please note that my experience with ReactiveUI so far is very close to zero so take the speculations below for what they are.. Speculations :) The root of the problem is that WhenActivated depends on external state (via activationFetcherCache) and throws an exception if that isn't initialized, unfortunately I'm not familiar enough with ReactiveUI to determine if this is the only (and best) way to do it. I think this would work if it would fail silently instead but doesn't feel like a perfect solution to me. Perhaps it would be possible to have a IVewForWinforms<> that implements a different IActivatable (IActivatableWinforms) and thereby binds to another implementation of Activate that can fail silently? This would still have the drawback of possible silent failures, but would at least limit them to WinForms.. So it certainly looks possible to work out on ReactiveUI side as far as I can see but question is if this narrow case that most WinForms devs will already have some mechanism to guard against (static IsRunning, using bool designMode = LicenseManager.UsageMode == LicenseUsageMode.Designtime and similar) is worth the work? The obvious limitation of not fixing as I see it is that WhenActivated won't be very usable for someone that distributes CustomControls, but to be honest, who does that these days except for established firms like DevExpress et. al. who still are very unlikely to depend on external (non standard MS) stuff. For me, when I write WinForms code and notice the designer breaking I put a if(IsRunning) on reflex. Perhaps this isn't the best way but it works and I have seen plenty of controls doing the same.. |
Generics & DesignerDid a couple hours of research into this tonight and blew right through the timebox and then some reading so much old technical content; sometimes via internet archive. The pattern Kent stumbled upon was brought up many times as being the path forward.
I'm happy with recommending via documentation and in the samples that users create these wrappers as it appears to be in line with what the rest of the ecosystem did. There was a Microsoft Connect bug opened re: generics and the designer and it was closed as WONTFIX. This article is a good read - might be able to use the http://www.pocketsilicon.com/post/Using-Visual-Studio-Whidbey-to-Design-Abstract-Forms Design Mode DetectionAs for detecting if in design mode; this was a good read @ https://stackoverflow.com/questions/34664/designmode-with-controls |
I'm finishing up some "official" samples for RxUI that will live alongside the in the main repo. Pretty keen to ship |
@ghuntley any news? |
@ehouarn-perret looking for someone to take lead on polishing up reactiveui-winforms. My preference is to keep the API consistent and UI agnostic. I've sent you a slack invitation - drop on by #reactiveui-winforms. |
The protected property DesignMode in each control can be used to check whether the designer is currently running. In my PR, I added a check to the ActivationForViewFetcher class. |
Sorry but I have to reopen that... but fix comes in 5 minutes. |
The DependencyResolverMixins did not register the ActivationForViewFetcher during the designtime, because the version of the specified assembly did not match. |
Note: I haven't tested this on anything before VS2015 Update 1.
Repro:
Then open the
WindowsFormsApplication1.sln
solution in Visual Studio, build the project and open theForm1
design view. You should see something like this:THIS IS IMPORTANT I THINK: The Don't know how to detect when WindowsFormsApplication1.CustomControl is activated/deactivated, you may need to implement IActivationForViewFetcher error can be traced to this code. I'm not really across everything that's happening when RxUI is loaded in a design time context - I'd love any help if others know more...
The stack trace is all kinds of boring:
As soon as I saw this I felt myself dragged back to the distant past, when I cared about the design time experience of WPF libraries and found myself immensely frustrated by all the rough edges that resulted when you tried to play the game. So I ran the other way.
So we have a top-level form that uses
WhenActivated
- it doesn't have an issue in the design view - and it hosts a childUserControl
which also uses `WhenActivated - but it triggers the error.I'm logging this for a couple of reasons:
WhenActivated
usage as a Good Thing To DoWhenActivated
seems to break for nested controls only - not surprising, maybe just a clue more than anythingI've not got the full picture on how much work is involved with fixing this, but given we keep getting WinForms questions I'd love to help make our story about it better - and this was something I found fairly early in my travels...
The text was updated successfully, but these errors were encountered: