KeyedCollection and d:DataContext Design Error - c#

See the update below for VS2013.
When using a class as a d:DesignInstance that exposes a KeyedCollection<TKey, TItem>, the XAML designer complains with the following warning:
The number of generic arguments provided doesn't equal the arity of
the generic type definition.
Parameter name: instantiation
The problem can be reproduced with the following simple program:
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Test"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance local:MyClass}" />
namespace Test
{
public partial class MainWindow : Window
{
public MainWindow() { InitializeComponent(); }
}
public class MyClass
{
public KeyedCollection<string, object> SettingsModule { get; private set; }
}
}
I'm unable to provide design time shape with any class that exposes a KeyedCollection.
Any ideas what is going on here?
Update: As of VS2013 the behavior of the designer in dealing with a KeyedCollection has changed (though still not fully working).
The above example no longer generates an error. However, if the KeyedCollection uses certain types (such as an interface) as the TItem the following error is generated:
Object reference not set to an instance of an object.
Consider the following example:
namespace Test
{
public partial class MainWindow : Window
{
public MainWindow() { InitializeComponent(); }
}
public class MyClass
{
public KeyedCollection<string, IInterface> MyCollection { get; private set; }
}
public interface IInterface
{
string Name { get; set; }
}
}

I've been able to resolve this issue by prefixing the design instance type with "d:Type" as such:
d:DataContext="{d:DesignInstance d:Type=local:MyClass}"
This seems to be a bug in the VS2013 designer. I believe the d:Type property should be the default property of the d:DesignInstance attribute. Also, strangely I've only seen this issue with the KeyedCollection class.
Furthermore, the MSDN examples of d:DesignInstance usage sometimes use "Type" with no prefix. In this example if d:Type is omitted or the prefix is missing, the design time error is generated as I mentioned.

If I have'nt misunderstood your question try it like
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Width="800" Height="800"
Title="MainWindow"
>
<Window.DataContext>
**<local:MyClass />**
</Window.DataContext>
<Grid x:Name="LayoutRoot">
</Grid>
I hope this will help.

I had to remove the Default Constructor from my DesignInstance-Class

Related

Cannot create inherited usercontrol in WPF, base control "does not exist" in local namespace

I've tried to make a custom UserControl, "UserControl1" in WPF that inherits from a base class. Among others I get this error in the XAML:
Error XDG0008 The name "ControlBase" does not exist in the namespace "clr-namespace:Temp".
I also get an error at DesignHeight & Width
The ControlBase class was availible in VS autocompletion.
The ControlBase class is defined in the namespace Temp.
I've tried changing keywords for the base class, for example adding partial.
UserControl1.xaml:
<local:ControlBase x:Class="Temp.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Temp"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
</Grid>
</local:ControlBase>
UserControl1.xaml.cs:
namespace Temp
{
/// <summary>
/// Interaction logic for UserControl1.xaml
/// </summary>
public partial class UserControl1 : ControlBase
{
public UserControl1()
{
InitializeComponent();
}
}
}
ControlBase.cs:
using System.Windows.Controls;
namespace Temp
{
public class ControlBase : UserControl
{
public ControlBase() { }
}
}
I expected UserControl1 to inherit from ControlBase without compiler errors.
I don't know what I did, but it fixed itself.

Is this definition of a dependency property with a generic owner class incorrect?

I have a custom generic user control that I wish to have a content property named as AdditionalContent. The cut down implementation with all non error specific code removed is.
[ContentProperty("AdditionalContent")]
public class WgReactiveUserControl<TViewModel> : UserControl
where TViewModel : class
{
public UIElement AdditionalContent
{
get { return ( UIElement ) GetValue(AdditionalContentProperty); }
set { SetValue(AdditionalContentProperty, value); }
}
public static readonly DependencyProperty AdditionalContentProperty =
DependencyProperty
.Register("AdditionalContent",
typeof(UIElement),
typeof(WgReactiveUserControl<TViewModel>),
new PropertyMetadata(null));
}
and I get the following error in the designer.
which refers to this code.
plain text code is
<w:MeasuredViewportLayoutHelpPanelBase
x:Class="Weingartner.EyeshotExtensions.MeasuredViewportLayoutHelpPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:w="clr-namespace:Weingartner.EyeshotExtensions"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
d:DataContext="{d:DesignInstance w:MeasuredViewportLayoutHelpPanelModel, d:IsDesignTimeCreatable=false}">
<Border BorderThickness="1" Background="#C0333333" BorderBrush="#C0D4D4D4" Margin="20">
</Border>
</w:MeasuredViewportLayoutHelpPanelBase>
with code behind being
public class MeasuredViewportLayoutHelpPanelModel
{ }
public class MeasuredViewportLayoutHelpPanelBase
: WgReactiveUserControl<MeasuredViewportLayoutHelpPanelModel>
{ }
public partial class MeasuredViewportLayoutHelpPanel
: MeasuredViewportLayoutHelpPanelBase
{
}
I can't figure out what might be wrong with the declaration of the dependency property AdditionalContent that will cause the designer to give this error.

DesignInstance does not work in VS2013

Visual Studio does not show design time data with DesignInstance attribute. I have checked DesignInstance with/without MVVM Light. I have spend a lot of time to fix the issue (checked similar queestions on StackOverflow too) but DesignInstance simply does not work.
Project:
SearchIdView.
SearchIdViewModel - real View Model.
DesignSearchIdViewModel - inherits from SearchIdViewModel and contains design time data (properties are assigned in constructor).
Environment:
VS2013 SP3
Net 4.0
MvvmLight 5.0.2.0
SearchIdView.xaml
<Window x:Class="App1.View.SearchIdView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ignore="http://www.ignore.com"
xmlns:design="clr-namespace:App1.Design"
mc:Ignorable="d ignore"
DataContext="{Binding SearchId, Source={StaticResource Locator}}"
d:DataContext="{d:DesignInstance d:Type=design:DesignSearchIdViewModel,IsDesignTimeCreatable=True}"
>
<Grid>
<TextBlock Text="{Binding Test}" />
</Grid>
SearchIdViewModel.cs
Property from SearchIdViewModel
public const string TestPropertyName = "Test";
private string _test;
public string Test
{
get
{
return _test;
}
set
{
Set(TestPropertyName, ref _test, value);
}
}
Do you have any idea why DesignInstance does not work in this case?
Workaround
remove d:DataContext from view
add interface ISearchIdViewModel (it is empty)
SearchIdViewModel inherits from ISearchIdViewModel
change ViewModelLocator (below)
ViewModelLocator.cs
public class ViewModelLocator
{
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<ISearchIdViewModel,Design.DesignSearchIdViewModel>();
}
else
{
SimpleIoc.Default.Register<ISearchIdViewModel, SearchIdViewModel>();
}
}
public SearchIdViewModel SearchId
{
get { return (SearchIdViewModel) ServiceLocator.Current.GetInstance<ISearchIdViewModel>(); }
}
}
Your d:DesignInstance declaration is malformed. You specify the property name d:Type instead of Type, so the property is not assigned correctly. Either replace d:Type with Type, or leave the property name off entirely and let it be inferred as the default property.
d:DataContext="{d:DesignInstance d:Type=design:DesignSearchIdViewModel,
IsDesignTimeCreatable=True}"
Should become:
d:DataContext="{d:DesignInstance Type=design:DesignSearchIdViewModel,
IsDesignTimeCreatable=True}"
Or, alternatively:
d:DataContext="{d:DesignInstance design:DesignSearchIdViewModel,
IsDesignTimeCreatable=True}"
(line wrapping added for readability)
Another cause that might make d:DesignInstance not to work is that all data must be properties not just public variables of mock class! I know that it was not your problem, but it should be checked if for someone it does not work.
Will not work with:
public class MockFile
{
public FilePRJO FilePRJO = new FilePRJO();
}
But it will work with:
public class MockFile
{
public FilePRJO _filePRJO = new FilePRJO();
public FilePRJO FilePRJO
{
get
{
return _filePRJO;
}
}
}

Changing base class for WPF page code behind

I have a simple class called CustomPage which inherits from Window:
public class CustomPage : Window
{
public string PageProperty { get; set; }
}
I want my MainWindow codebehind to inherit from CustomPage as follows:
public partial class MainWindow : CustomPage
{
public MainWindow()
{
InitializeComponent();
}
}
Unfortunately, I get the following error:
Partial declarations of 'WpfApplication1.MainWindow' must not specify different base classes
I can set x:Class to "WpfApplication1.CustomPage" in MainWindow.xaml, but then it appears I don't have access to the UI elements defined in MainWindow.xaml...
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
}
public class CustomPage : Window
{
public string PageProperty { get; set; }
}
<myWindow:CustomPage x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:myWindow="clr-namespace:WpfApplication4"
Title="MainWindow" Height="800" Width="800">
<Grid>
</Grid>
</myWindow:CustomPage>
I hope this will help.
You need to update your xaml like this -
<local:CustomPage x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1">
</local:CustomPage>
Here, local is your namespace where CustomPage and MainWindow resides.
As the error suggested, you can't declare different base classes for partial declaration of class. So, in XAML too, you need to use the CustomPage instead of WPF Window

How to add custom-control-derived TabItem to TabControl in WPF?

I want to have my own base TabItem class and use other classes that derive from it.
I define base class in MyNs namespace like this:
public class MyCustomTab : TabItem
{
static MyCustomTab()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomTab), new FrameworkPropertyMetadata(typeof(TabItem)));
}
}
And this is what I do for the class that inherits from it:
code-behind in MyNs namespace:
public partial class ActualTab : MyCustomTab
{
public ActualTab()
{
InitializeComponent();
}
}
XAML:
<MyCustomTab x:Class="MyNs.ActualTab"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
</Grid>
</MyCustomTab>
The error I get is "The tag 'MyCustomTab' does not exist in XML namespace 'http://schemas.microsoft.com/winfx/2006/xaml/presentation'". If I use TabItem tag in XAML the error says that it's not possible to define to different base classes.
How to fix this?
Ok, I'm stupid, it should've been
<MyNs:MyCustomTab x:Class="MyNs.ActualTab"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:MyNs="clr-namespace:MyNs">
<Grid>
</Grid>
</MyNs:MyCustomTab>

Categories

Resources