Changing base class for WPF page code behind - c#

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

Related

How can I access inherited members in a WPF window?

I am trying to create a base class for my windows in a WPF application but I cannot access their members in the derived classes. For example, here is the base window:
namespace MyApp.Windows
{
public class BaseWindow : Window
{
public int MyProp { get; set; }
}
}
And here is a window:
public partial class SomeWindow : BaseWindow
{
public SomeWindow()
{
InitializeComponent();
Loaded += SomeWindow_Loaded;
}
private void SomeWindow_Loaded(object sender, RoutedEventArgs e)
{
MyProp = do something;
}
}
If I leave it like this, the MyProp proerty works just fine but I get an error that InitializeComponent() is not recognized. Therefore, in the window xaml I change the x:Class as follows:
Before
<Window x:Class="MyApp.SomeWindow"
After
<Window x:Class="MyApp.Windows.BaseWindow"
Now, InitializeComponent() doesn't give me anymore issues but MyProp suddenly isn't recognized. Why?
In case it helps, what I want is to have all windows raise an event once they are loaded (the Loaded event is fired) and I don't want to write this code for every window I have, so I thought I could write this code in a base class, derive my windows from this and, well, have everything work.
Edit: Here's all the code.
BaseWindow.cs (no other xaml):
using System.Windows;
namespace MyApp.Windows
{
public class BaseWindow : Window
{
public int MyProp { get; set; }
}
}
MainWindow.xaml.cs
namespace MyApp.Windows
{
public partial class MainWindow : BaseWindow
{
public MainWindow()
{
InitializeComponent();
}
}
}
MainWindow.xaml:
<myapp:BaseWindow x:Class="MyApp.Windows.BaseWindow"
xmlns:myapp="clr-namespace:MyApp.Windows"
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:local="clr-namespace:MyApp"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</myapp:BaseWindow>
In order to change the base class of SomeWindow from Window to BaseWindow, you need to replace Window by BaseWindow wherever it occurs.
So
public partial class SomeWindow : Window
becomes
public partial class SomeWindow : BaseWindow
and
<Window x:Class="MyApp.Windows.SomeWindow" ...>
becomes
<myapp:BaseWindow x:Class="MyApp.Windows.SomeWindow"
xmlns:myapp="clr-namespace:MyApp.Windows" ...>
with the unavoidable XAML namespace prefix.
This is the BaseWindow class used in the example above:
namespace MyApp.Windows
{
public class BaseWindow : Window
{
public int MyProp { get; set; }
public BaseWindow()
{
Loaded += BaseWindow_Loaded;
}
private void BaseWindow_Loaded(object sender, RoutedEventArgs e)
{
}
}
}

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.

Adding derived UserControls to List<> in Wpf

Im trying to create a list of wpf user controls and then set the mainwindows content to the usercontrol at runtime.
Since all UserControls will also share interfaces I want to build them from a derived window class as such:
public class BaseControl : UserControl, IControlState
public string ControlName
{
get
{
return this.GetType().Name;
}
}
public void UseState(object parameters)
{
throw new NotImplementedException();
}
}
Class derived from UserControl
public partial class Buglist : UserControl
{
public Buglist()
{
InitializeComponent();
}
}
Class derived from my BaseControl
public partial class Login : BaseControl
{
public Login()
{
InitializeComponent();
}
}
The Login xaml to allow Visual Studio designer to recognize a designable component
<MyType:BaseControl x:Class="BugAnalyzer.Controls.Login"
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:BugAnalyzer.Controls"
xmlns:MyType="clr-namespace:BugAnalyzer.Controls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="112,72,0,0" TextWrapping="Wrap" Text="login" VerticalAlignment="Top"/>
</Grid>
In my main window I want to be able to add these controls to a list and then be able to access shared properties such as ControlName.
public partial class MainWindow : Window
{
List<UserControl> uclist = new List<UserControl>();
List<BaseControl> bcList = new List<BaseControl>();
public MainWindow()
{
InitializeComponent();
Buglist UserControlDerivedWindow = new Buglist();
Login BaseControlDerivedWindow = new Login();
uclist.Add(UserControlDerivedWindow); //Works
bcList.Add(BaseControlDerivedWindow); //Fails
}
why can I add the class derived from UserControl to a list UserControls
but not a class derived from BaseControl to a list of BaseControls?
Strangely I have solved this though I not sure what the root issue was
For clarity in the question I wrote
Login BaseControlDerivedWindow = new Login();
but the actual code was
Login login = new Login();
which caused the compiler to issue something like "
Cannot covert from Program.Controls.Login to Program.Controls.BaseControl"
after I changed the code for clarity it compiled and then let me rename the Login instance back to login and compiled no issues again.

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.

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