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

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>

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.

How to bind to a property of a class instantiated in the current class

I have two clasess, MainWindow and MainWindow_ViewModel.
MainWindow is defined like so:
public partial class MainWindow : Window
{
static public MainWindow wn;
public MainWindow_ViewModel mwvm;
public MainWindow()
{
InitializeComponent();
wn = this;
mwvm = new MainWindow_ViewModel();
}
}
MainWindow_ViewModel is defined like this:
class MainWindow_ViewModel
{
private List<String> _filtros;
public List<String> filtros
{
get
{
return _filtros;
}
}
public MainWindow_ViewModel()
{
_filtros = new List<String>();
_filtros.add("Filtro1");
_filtros.add("Filtro2");
_filtros.add("Filtro3");
}
}
Notice that there is no static methods or properties whatsoever.
In MainWindow's XAML I have a ListBox that I want to bind with the mwvm.filtros which should be available directly from code-behind.
How can I achieve that WITHOUT using DataContext and only in XAML?
Could it be possible to bind from another class (i.e. another window) to the following path? MainWindow.wn.mwvm.filtros.
Yes, of course. You don't need C# code to bind the view model. Just create an object in the DataContext element:
<Window.DataContext>
<local:MainWindow_ViewModel />
</Window.DataContext>
You have to create a namespace for your local project though. Full code:
<Window x:Class="Your.Namespace.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Your.Namespace"
>
<Window.DataContext>
<local:MainWindow_ViewModel />
</Window.DataContext>
You can't bind from another Window or Control unless you pass it along or make it static. If it is sub control of this Window, you can set its data context.

KeyedCollection and d:DataContext Design Error

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

XAML DataContext DesignInstance with nested types

Is it possible to specify a nested type for d:DesignInstance in XAML? And if so, how?
If I have the following class structure:
namespace MyApp
{
public class OuterClass
{
public class InnerClass
{
public string SomeData {get;set;}
}
}
}
How can I use the InnerClass type as a DesignInstance? The following doesn't work:
<phone:PhoneApplicationPage
...
xmlns:local="clr-namespace:MyApp"
...
d:DataContext="{d:DesignInstance Type=local:OuterClass.InnerClass}"
>
Try changing . to +. Something like:
<phone:PhoneApplicationPage
...
xmlns:local="clr-namespace:MyApp"
...
d:DataContext="{d:DesignInstance Type=local:OuterClass+InnerClass}">

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

Categories

Resources