Goal:
To create a WPF user control that implements basic functionality from a non-GUI interface, and delegating the rest through abstract methods.
Attempt 1:
- Defined a base WPF user control BaseWpfControl using XAML.
public abstract partial class BaseWpfCustomPropertyEditor : UserControl, Interface1 { …} - Then, extend BaseWpfControl, like so:
<local:BaseWpfControl x:Class="MyNameSpace.LoginEditorControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyNameSpace"
Height="206" Width="595">
<Grid Height="300" Width="418">
<Grid Margin="10,10,-75,120">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="210*" />
<ColumnDefinition Width="118*" />
<ColumnDefinition Width="155*" />
</Grid.ColumnDefinitions>
<Label Height="33" Margin="6,-1,67,0" Name="label1" VerticalAlignment="Top">Host Name:</Label>
<TextBox Height="23" Margin="12,25,23,0" Name="txtHostName" TextChanged="txtHostName_TextChanged" VerticalAlignment="Top" Grid.ColumnSpan="3" />
<Label Height="29" Margin="6,47,88,0" Name="label2" VerticalAlignment="Top">User Name:</Label>
<TextBox Height="23" Margin="12,71,23,0" Name="textBox1" VerticalAlignment="Top" Grid.ColumnSpan="3" TextChanged="textBox1_TextChanged" />
<Label Height="25" Margin="6,102,94,0" Name="label3" VerticalAlignment="Top">Password:</Label>
<PasswordBox Height="23" Margin="12,133,23,0" Name="passwordBox1" VerticalAlignment="Top" Grid.ColumnSpan="3" PasswordChanged="passwordBox1_PasswordChanged" />
</Grid>
</Grid>
</local:BaseWpfCustomPropertyEditor> - Got compile-time error: "cannot be the root of a XAML file because it was defined using XAML""
Conclusion: WPF user controls were designed for composition, not inheritance.
Attempt 2:
- Instead of using XAML, simply defined BaseWpfControl as a class that extends System.Windows.Controls.UserControl
- Repeat Attempt 1.2
- Now compiles fine. But when trying to bring up LoginEditorControl, got error:
”Problem Loading … Could not create an instance of type “BaseWpfControl…” - Double-checked, BaseWpfControl did have a default constructor
- Removed abstract partial keyword in base class Same problem
- Searched the web; found this https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=292693:
”Hello, if you mark your base generic class as abstract, the designer does not work. I understand this might not be a supported scenario and I'd live with this, if:
1) it would not work with non-abstract classes as well,
2) all the XAML code would not get underlined, that is really crazy.”
Sub-Goal 1.1:
- how to make an abstract WPF base control editable in the UI designer?
Attempt 1.1.1:
- Per http://www.urbanpotato.net/default.aspx/document/2001, annotated BaseWpfControl with
[TypeDescriptionProvider(typeof(GeneralConcreteClassProvider))]
[ConcreteClass(typeof(UserControl))] - didn’t help … same error “Could not create an instance of …”
Attempt 1.1.2:
- Removed abstract keyword from BaseWpfControl .
- Bring LoginEditorControl control back in the VS2008 Visual Designer. Got message:
”The document root element is not supported by the visual designer” - Changing base class for BaseWpfControl to ContentControl didn’t help.
- If we changed to using XAML for BaseWpfControl, then we’d be back to problem 1.3
Attempt 1.1.3: immediate work-around
- Remove abstract keyword from BaseWpfControl
- commented out the line:
public partial class LoginEditorControl : UserControl, BaseWpfControl { - Replaced with:
public partial class LoginEditorControl : UserControl { - Replaced XAML declaration
<local:BaseWpfControl x:Class="MyLib1.LoginEditorControl " xmlns:local="clr-namespace:MyLib1"
with
<UserControl - Edit the control in VS Visual Designer, then undo steps 1-4 prior to running.
Stopped experimenting here. If I had had more time, I would have liked to try these:
Attempt 1.1.4: better workaround – use XamlPad
Previous process was too cumbersome to undo. Use XamlPad to edit the control GUI, and then paste he result back to the VS project.
Attempt 1.1.5: How to overcome restriction of “multiple class inheritance”?
Use Events instead.
5 comments:
Did you try using the property:
DesignerProperties.GetIsInDesignMode
No, I haven't, but will try on the next opportunity. Thanks for the tip.
They suck
Microsoft's employees are so ignorant
what if DesignerProperties.GetIsInDesignMode also doesnt work?
Post a Comment