InitializeComponent "doesn't exist" and "no definition" for XAML map controls - c#

I am working on a simple map app that will zoom into and follow my location using GeoCoordinateWatcher. The problem is, whenever I finish putting everything into place, InitializeComponents() always throws an exception and my C# code won`t recognize my XAML map controls. Is this some kind of bug or am I just a total fool?
CODE SAMPLE:
public MainPage()
{
this.InitializeComponent(); // This whole line is underlined red
this.NavigationCacheMode = NavigationCacheMode.Required;
}
public void CenterUserLocation()
{
// Center MyMap on user location
this.MyMap.Center = myPoint; //MyMap is underlined red
this.MyMap.ZoomLevel = 10; //MyMap is underlined red
}
UPDATE: (Class Definitions C#)
namespace MapApp{
public sealed partial class MainPage : Page
{
GeoCoordinateWatcher watcher;
private Geopoint myPoint;
UPDATE: (XAML)
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MapApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Maps="using:Windows.UI.Xaml.Controls.Maps"
x:Class="MapApp.MainPage"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page.BottomAppBar>
<CommandBar>
<!-- LOCATION BUTTON -->
<AppBarButton x:Uid="LocateAppBarButton"
x:Name="LocateAppBarButton"
Label="location"
Icon="Map"
Click="LocateAppBarButton_Click" />
</CommandBar>
</Page.BottomAppBar>
<Grid>
<Maps:MapControl x:Name="MyMap" HorizontalAlignment="Left" VerticalAlignment="Top" Height="580" Width="400"/>
</Grid>
</Page>

Your XAML and code-behind should be something like this:
XAML:
<Page x:Class="MyNamespace.MyCanvasCodeInline">
...
Code-behind:
namespace MyNamespace
{
public partial class MyCanvasCodeInLine // : Page - not needed but implied
...
Things you should check:
The code-behind class is defined as partial
The code-behind class qualified name (namespace + class name) is the same as the x:Class property of the XAML root node
The XAML root node is some class that implements IComponentConnector (Page, Window, UserControl, etc.)
Another way to do this is checking the xaml.cs file that gets generated "under" the XAML file, and compare its partial class definition with your code-behind class. They should match types, name and namespace.

Make sure that your XAML file has the correct Build Action (should be Page). I've seen Visual Studio change this when copy/pasting XAML files between projects.
If this isn't correct, you will get this error even though your class names and namespaces match between your XAML and code-behind.

Related

How do I reference a custom property value in a WPF UserControl via Binding?

I'm building a WPF app with custom UserControls, and I'm trying to understand how property bindings are supposed to work. I can't get even the most basic binding to work, and it's simple enough to distill into a tiny example, so I figured someone with more WPF experience might be able to put me on the right track.
I've defined a custom UserControl called TestControl, which exposes a Foo property, which is intended to be set in XAML whenever a UserControl is placed.
TestControl.xaml.cs
using System.Windows;
using System.Windows.Controls;
namespace BindingTest
{
public partial class TestControl : UserControl
{
public static readonly DependencyProperty FooProperty = DependencyProperty.Register("Foo", typeof(string), typeof(TestControl));
public string Foo
{
get { return (string)GetValue(FooProperty); }
set { SetValue(FooProperty, value); }
}
public TestControl()
{
InitializeComponent();
}
}
}
The markup for TestControl just defines it as a control with a single button, whose label text displays the current value of the Foo property:
TestControl.xaml
<UserControl x:Class="BindingTest.TestControl"
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:BindingTest"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Button Content="{Binding Foo}" />
</Grid>
</UserControl>
In my MainWindow class, I just place a single instance of TestControl with its Foo property set to "Hello".
MainWindow.xaml
<Window x:Class="BindingTest.MainWindow"
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:BindingTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<local:TestControl Foo="Hello" />
</Grid>
</Window>
I would expect that when I build and launch this app, I'd see a window with a single button reading "Hello". However, the button is blank: the Binding doesn't seem to work.
If I add a click handler to the TestControl's button, I can verify that the value is being updated behind the scenes:
// Added to TestControl.xaml.cs:
private void Button_Click(object sender, RoutedEventArgs e)
{
Console.WriteLine("Button clicked; Foo is '{0}'", Foo);
}
// Updated in TestControl.xaml:
// <Button Content="{Binding Foo}" Click="Button_Click" />
When I click the button, I get Button clicked; Foo is 'Hello', but the GUI never updates. I've tried using Path=Foo, XPath=Foo, etc., as well as setting UpdateSourceTrigger=PropertyChanged and verifying updates with NotifyOnTargetUpdated=True... nothing seems to result in the text in the UI being updated to match the underlying property value, even though the property value seems to be getting updated just fine.
What am I doing wrong? I feel like there's just a simple and fundamental misunderstanding in how I'm approaching this.
edit:
Poking around a bit more and reading similar questions has led me to a potential fix: namely, adding a name to the root UserControl element in TestControl.xaml (x:Name="control"), and changing the binding to explicitly specify that control ({Binding Foo, ElementName=control}).
I'm guessing that by default, {Binding Foo} on the Button element just means "find a property named 'Foo' on this Button control", whereas I'd assumed it'd mean "find a property named 'Foo' in the context that this Button is being declared in, i.e. on the TestControl".
Is specifying an explicit ElementName the best fix here?
You have to set the source object of the Binding to the UserControl instance, e.g. like this:
<Button Content="{Binding Foo, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
or
<UserControl ... x:Name="theControl">
...
<Button Content="{Binding Foo, ElementName=theControl}"/>
If you have many such Bindings, you may also set the DataContext of the top level element in the UserControl's XAML to the UserControl instance:
<Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}">
<Button Content="{Binding Foo}" />
<Button Content="{Binding Bar}" />
</Grid>
You must however avoid to set the DataContext of the UserControl (which is often recommend by "expert" bloggers), because that would break DataContext-based Bindings of the UserControl properties like
<local:TestControl Foo="{Binding SomeFoo}" />

GMap.NET C# WFP: Can i add custom UserControl into GMapControl overlays?

Project: c#, wpf, .net4.0, Gmap.Net.Presentation 1.7.1.
What I have:
My custom MapControl class inherited from GMap.NET.WindowsPresentation.GMapControl class.
public sealed class MapControl : GMapControl
{
/* Some special data. */
public MapConrol()
: base()
{
/* Some init actions. */
}
/* Overrided and additional methods. */
}
And, for example, I have some custom UserControl class.
Code:
public sealed partial class MapObjectMarkerUiControl : UserControl
{
/* Some special data. */
public MapObjectMarkerUiControl()
{
/* Some init actions. */
}
/* Overrided and additional methods. */
}
Xaml:
<UserControl x:Class="MapCustomControls.MapObjectMarkerUiControl"
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"
mc:Ignorable="d"
Width="40" Height="40" RenderTransformOrigin="0.5, 0.5">
<Grid>
<!-- Some visual controls: text, buttons, etc. -->
</Grid>
</UserControl>
Example of custom user control:
What I need:
Is there any way to add it to the map with reference to the geo coordinates? Something like this one:
gmap.AddCustomUserControl(UserControl customMarker, double latitude, double longitude);
May be I should to inherit my UserControl from other class or implement some Gmap.NET interface that allow to add my widget to the map.
Any advice, tips, help?
P.S. If I solve this problem, I will post it here. I guess it will very helpful for others.
Also, I found a lot of questions about GMap on StackOverflow and so on, and everywhere I saw Overlay class.
GMapOverlay markersOverlay = new GMapOverlay("markers");
gmap.Overlays.Add(markersOverlay);
In my verstion I haven't this one. I have already exist built-in marker overlay into GMap class.
gmap.Markers - ObservableCollection of the GMapMarkers.
And there is no way to create my own overlays and add it to GMapControl object.
UPDATE 0:
First idea in my head. Just add GMapMarkers on the map with some special tag by id of map object, for example. And OnRender() of the GMapControl find all the markers on the screen, parse their ids and draw above my wpf UserControls. But I hope there is some internal mechanics in the GMapControl for that.
I believe the solution is easier than what you've tried, you can derive from GMapMarker, e.g.:
class CustomMarker: GMapMarker
{
public string Description { get; set; }
public CustomMarker(PointLatLng pos, string description)
: base(pos)
{
Description = description;
Shape = new CustomMarkerElement();
((CustomMarkerElement)Shape).lblDesc.Content = description;
}
}
This marker instance gives you access to the UI properties within an own CustomerMarkerElement (an UserControl within the project):
<UserControl x:Class="WpfApplication3.CustomMarkerElement"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Ellipse
Fill="DarkKhaki"
Height="40"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="40" />
<Label
x:Name="lblDesc"
Content="TST"
Foreground="White"
FontWeight="Bold"
HorizontalAlignment="Left"
HorizontalContentAlignment="Center"
Margin="0,6"
VerticalAlignment="Top"
Width="40"/>
</Grid>
</UserControl>
The downside is that afaik there is no way to have this in an MVVM conform way (e.g. define the custom markers within an item template).

c# UserControl base class inheritance

I have a base class call PopupWindow which inherits from UserControl. PopupWindow has no associated xaml page, its just a regular class which inherits from UserControl
I then have another UserControl which inherits from PopupWindow. Now this is a proper user control in that is has an associated xaml page.
I have changed the root xaml tag to be PopupWindow like this
<local:PopupWindow
.....
</local:PopupWindow>
where local is the namespace in this PopupWindow exists.
But I keep getting an error that PopupWindow does not exist in the given namespace.
What am I doing wrong?
Thanks
I've managed to get this working as follows:
Parent control:
public class PopupWindow : UserControl
{
}
Inheriting control:
Code behind:
public partial class PopupWindowChild
{
public PopupWindowChild()
{
InitializeComponent();
}
}
XAML:
<Controls:PopupWindow x:Class="MyNamespace.Controls.PopupWindowChild"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:MyNamespace.Controls">
<TextBlock Text="Blah" />
</Controls:PopupWindow>
Main view:
<Window x:Class="MyNamespace.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:MyNamespace.Controls">
<Controls:PopupWindow />
</Window>
Your XAML won't recognise your control until the code is built. Once built and run, I'm seeing "Blah" in my main view as expected.

Different base class in the XAML file

I have a class called BIFUserControl which inherits from UserControl class. Now I am designing a new user control called BIFText which inherits from BIFUserControl class. So, I changed the XAML file called BIFText.xaml as follows :
<base:BIFUserControl
xmlns:base="clr-namespace:BaseInputFramework.BaseWidgets;assembly=BaseInputFramework"
x:Class="BIFWidgetLibrary.Text.BIFText"
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:mp="clr-namespace:Microsoft.Multipoint.Sdk.Controls;assembly=Microsoft.Multipoint.Sdk.Controls"
xmlns:utils="clr-namespace:BaseInputFramework.BaseWidgets.Utils;assembly=BaseInputFramework"
mc:Ignorable="d"
d:DesignHeight="150" d:DesignWidth="150">
<Grid>
</Grid> </base:BIFUserControl>
And then I changed my BIFText.xaml.cs file as follows:
namespace BIFWidgetLibrary.Text {
public partial class BIFText : BIFUserControl
{
public BIFText()
{
InitializeComponent();
}
} }
But now when I try to build the project, I get the following error message :
'BaseInputFramework.BaseWidgets.BIFUserControl' cannot be the root of a XAML file because it was defined using XAML. Line 2 Position 14.
Can someone please help me with this error. Thanks in advance.
Error says itself that BaseInputFramework.BaseWidgets.BIFUserControl cannot be root of a XAML file since it is defined using XAML. Only elements which are not defined using XAML file can only be root element. Refer to these links - Cannot define root element and Inheriting from UserControl
UserControls work by setting the Content to what you define in XAML, this might be the reason why you cannot inherit like that: The base class' content would be overwritten.
If you don't mind completely replacing the content you might as well use a custom control and define a Template instead.

Changing from WPF User Control to Window?

I've been working on a commandline application, and have recently decided to add a wpf window to the application. I added this as a UserControl, however I noticed I can't call this class using ShowDialog() from my main code;
I've tried changing the Base class from a UserControl to Window, however an error occurs;
public partial class UserControl1 : Window
{
public UserControl1()
{
InitializeComponent();
}
Error 1 Partial declarations of
'ExcelExample.UserControl1' must not
specify different base
classesExcelExample
I've added all the references found in my other WPF application to no avail. Help!
In order to change the base class it is not sufficient to change it in code only. You must also change the root tag and any nested elements in accompanying XAML file. For example, you have something like:
<UserControl x:Class="Your.Namespace.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
</UserControl.Resources>
</UserControl>
You must change it to something like:
<Window x:Class="Your.Namespace.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window.Resources>
</Window.Resources>
</Window>

Categories

Resources