WPF CustomControl can't inherit from TextBlock control - wpf

I'm making a WPF CustomControlLibrary with CustomControls which inherit from standard controls like Label, TextBox etc.
When i try to make another CustomControl which inherit from TextBlock, i get strange errors.
It seems to be that a CustomControl can't inherit from the TextBlock.
But why?
Thanks in advance!

I have just created custom control inherited from TextBlock:
using System.Windows.Controls;
namespace WpfApplication1
{
public class CustomTextBlock : TextBlock
{
}
}
and used it within the same project:
<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">
<Grid>
<local:CustomTextBlock Text="Hello" />
</Grid>
</Window>
So the anser is: you can inherit from TextBlock
however, in order t use it in xaml, you have to compile the project first. There may be other errors in your code that prevents the project to compile and therefore you may be getting also errors like
The type 'local:CustomTextBlock' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built
or simmilar error:
The name "CustomTextBlock" does not exist in the namespace "clr-namespace:WpfApplication1".
Once you fix the other errors, these will disappear as well.

Related

Placing Custom WPF Control inside of a StackPanel

I'm trying to create a custom WPF control and place it inside of a StackPanel in my XAML file. I originally made a custom UserControl and got the following error message:
A value of type 'CustomControl' cannot be added to a collection or dictionary of type 'UIElementCollection'.
I tried changing my custom control from a UserControl to a UIElement, but I still get this message. How do I make a custom control that I can place inside of the StackPanel?
Restart Visual Studio. The XAML designer is a notoriously sensitive beast.
How are you creating the CustomControl? Make sure it is inheriting from UserControl.
I just created a new project called "TestProj" - right clicked in the solution explorer Add=>UserControl and named it CustomControl.
I was able to insert it via the following code:
<Window x:Class="TestProj.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestProj"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel>
<local:CustomControl/>
</StackPanel>
</Grid>
This could also happen if you're subclassing another control class, but your .xaml.cs file is still subclassing UserControl.

Silverlight: Access XAML control from code

I'm having a problem accessing a Panel control defined on the XAML of a page, the XAML is defined this way:
<UserControl
x:Class="PhoneBook.SilverlightMainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
mc:Ignorable="d" Width="400" Height="300" d:DesignWidth="993" d:DesignHeight="887">
<Grid x:Name="LayoutRoot" />
</UserControl>
The class is defined like this:
public partial class SilverlightMainPage : UserControl
{
public SilverlightMainPage()
{
InitializeComponent();
}
}
And I'm trying to instantiate it this way:
var silverlightMainPage = new PhoneBook.SilverlightMainPage();
SomeMethod((silverlightMainPage.LayoutRoot);
What I find strange is that when I put the dot after the object instance, it actually list LayoutRoot as one of the members, but when I try to compile the application it says that there's no member with that name.
Any ideas of what can be hapenning?
Thanks
EDIT: I also tried creating a property on the SilverlightMainPage class that returned the LayoutRoot element, but it also says that the class doesn't contain a definition for Layout root.
Is there any chance that you're trying to access SilverlightMainPage.LayoutRoot from a different assembly? In the MainPage.g.i.cs file, LayoutRoot (and all other controls defined in XAML) are marked "internal", i.e.:
internal System.Windows.Controls.Grid LayoutRoot;
You might want to try creating a public rather than an internal property that does a FindName("LayoutRoot") and returns the appropriate control.
Actually I found the problem.
I was generating the project automatically with a tool built by someone else in the company.
I did some extra tests and added a new UserControl to the project and tried to access the LayoutRoot from a property in the code behind, and it worked.
Then copied the exact same code to the file with the problem (just changing the class name) and it didn't compile.
Then I checked the project file, and found a section like this:
<ItemGroup>
<Compile Include="SilverlightMainPage.xaml.cs">
<DependentUpon>SilverlightMainPage.xaml</DependentUpon>
</Compile>
</ItemGroup>
Which for some reason was causing the compilation to fail.
I removed that section and now everything works fine.
Thanks for your answers though.

wpf custom control not recognized

This is my first foray into custom controls, and it's not going well. I have a custom graph control derived from Canvas.
namespace Grapher2 {
public class SeriesManager : Canvas {
public SeriesManager() {
...
}
}
}
It's defined in the same project and namespace as my app. I tried adding a reference to the control in XAML as follows:
<Window x:Class="Grapher2.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:graph="clr-namespace:Grapher2"
Title="Grapher" Width="800" Height="600">
<StackPanel Name="container" Width="700" Height="500">
<graph:SeriesManager Name="seriesManager" Width="700" Height="500" />
</StackPanel>
But when I try to reference the control name "seriesManager" in the code-behind for the Window, I get "The name 'seriesManager' does not exist in the current context."
Furthermore, the XAML editor will not render the Window, giving a huge stack trace with the error: "Type 'MS.Internal.Permissions.UserInitiatedNavigationPermission' in Assembly 'PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' is not marked as serializable."
I imagine the solution is something stupidly simple for anyone who's done custom controls. But I'm stumped.
did you try x:Name="seriesManager" in your xaml?
Edit: This may not be the issue seeing how you said your xaml isn't rendering. I'm guessing once you get the xaml to render in the designer... the code behind will work better.
Edit 2: Whenever I've had a problem with the designer rendering, it's because I'm doing something in the constructor of my custom control. Check your SeriesManager to see if you are doing something in its constructor that is causing a problem. Maybe you are referencing something that doesn't exist yet. If you do have extra code in your constructor, consider moving it to the UserControl_Loaded event.
Backing up Scott's answer here, since he helped me solve it:
What I did wrong was trying to access the control BEFORE InitializeComponent(), but was confused by 2 other error messages somewhere else in the code.
Just in case someone else has this error.

Overspecified Namespace in UserControl fails WPF Build

I have a very simple user control, and I'm trying to instantiate it in XAML. I find that when I go a bit overzealous with the namespacing, I run into problems with x:Name.
Here is my UserControl:
<UserControl x:Class="UserControlTest.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="300" Height="300">
<Grid>
<Label Name="Label1">Label</Label>
</Grid>
</UserControl>
Here is the code-behind for the UserControl:
Namespace UserControlTest
Partial Public Class UserControl1
End Class
End Namespace
Now, note that I have the root namespace of my VB.Net project set to "UserControlTest". Knowing that, have a look at my main window:
Here is my main window:
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:control="clr-namespace:UserControlTest.UserControlTest"
Title="Window1" Height="300" Width="300">
<Grid>
<control:UserControl1 />
</Grid>
</Window>
See how the control alias needs to have "UserControlTest.UserControlTest"? That's because I have the root namespace of my project set to UserControlTest, and I have defined the namespace of the UserControl to be UserControlTest, also. If I don't use a namespace for the UserControl, I don't have any troubles.
However, because I have done this, the build fails should I try to apply an x:Name to the UserControl, as follows:
<control:UserControl1 x:Name="test"/>
That will fail the build, with this error:
Type 'UserControlTest.UserControlTest.UserControl1' is not defined.
Can anybody explain why? Do I need to avoid putting my UserControls into namespaces just so I can give them x:Name values? I'd like to manipulate my UserControls from code-behind, and without an x:Name, I'm up the creek. But I don't want to sacrifice namespace usage just to get it!
Thanks very much.
I had the same problem (after rebuilding the project, first it worked fine...). I put UserControl into separate namespace.
What is the namespace defined as in the code-behind of your user control?
If your project was called Foo and you had a folder called Controls inside that project, any new user control added to that folder would be given the namespace Foo.Controls.
Then in your XAML you can reference it like so:
xmlns:Controls="clr-namespace:Foo.Controls"
...
<Controls:UserControl1 x:Name="uc1"/>
It seems like you have a naming issue.
EDIT:
Here's how I'm doing it in a project of mine.
StatusBar.xaml.cs
namespace Client.Controls.UserControls
{
public partial class StatusBar : UserControl
{
...
}
}
StatusBar.xaml
<UserControl x:Class="Client.Controls.UserControls.StatusBar">
</UserControl>
Main.xaml.cs
using Client.Controls.UserControls;
namespace Client
{
public partial class Main : Window
{
...
}
}
Main.xaml
<Window x:Class="Client.Main"
xmlns:UserControls="clr-namespace:Client.Controls.UserControls">
<UserControls:StatusBar x:Name="mainStatusBar" />
</Window>
I encountered the same problem in a vb.net project, and despite trying the suggestions here and elsewhere, could not solve the issue. In fact, I was able to take the exact same code out of our project to a new project, and it worked just fine (as far as I could determine all the configuration in the new project was identical). In the solution provided by David, I notice he is using c# - I am wondering if this is some weirdness associated with vb.net.
In the end, the user control I needed to use was quite simple and I implemented it as a resource ControlTemplate to get around the issue. Sorry I don't have a better answer, I am really not happy wih my findings...

Inheriting from a UserControl abstract subclass

I have a set of UserControls that need to have a few similar properties. Thus I have defined an abstract subclass of UserControl that defines these properties and updated the .xaml.cs and .g.cs files to inherit from this base class. All compiles well and runs well. Great! But.... .g.cs files are generated and will be regenerated, so how do I tell Blend or Visual Studio to keep inheriting from my base class rather than UserControl?
You need to change the XAML a bit to prefix the UserControl declaration with a namespace:
<local:MyBaseControl x:Class="MyNameSpace.MyControl"
xmlns:local="clr-namespace:MyNameSpace"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Content -->
</local:MyBaseControl>
Where MyNameSpace is your namespace (duh!), MyBaseControl is your base class and MyControl is your control that inherits from MyBaseControl. The x:Class part doesn't need to be in the same namespace, I've just kept it the same for the example.
More info here and here.

Resources