Setting Window.Datacontext - wpf

I am trying to use my viewmodel as my window's datacontext but am getting the error:
ViewModel is not supported in a Windows Presentation Foundation (WPF) project.
Clearly, I am not understanding something about the syntax and databinding my window to my view model, but I am not sure what it is that I don't know.
Any advice on what I should be reading?
<Window x:Class="SunnyBeam.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SunnyBeam" Height="488.358" Width="1014.552">
<Window.DataContext>
<ViewModel/>
</Window.DataContext>
<Grid>
</Grid>
</Window>

Usually I set DataContext through codebehind like that:
public partial class Flor1 : Window
{
public Flor1()
{
var dc = new MyViewModel();
dc.LoadData();
DataContext = dc;
InitializeComponent();
}
}
In place of MyViewModel may be anything you want to bind to.

define class like
public class ViewModel
{
public string Name { get; set; }
public ViewModel()
{
}
}
Use it in xaml like
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="clr-namespace:WpfApplication2"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<ui:ViewModel/>
</Window.DataContext>
<Grid>
</Grid>
It should work.

I thought I would throw in my experience with this error.
I had my datacontext setup same as below, and kept getting an error that ViewModel didn't exist, which I know it did. I refused to set it in code behind, simply rebuilding my project actually fixed this error.
<Window.DataContext>
<ViewModel/>
</Window.DataContext>

Related

How to do this.DataContext = this: in XAML....for eg<Window.DataContext> <local:MainWindow/></Window.DataContext>-->

Although the result is same after compiling and running the code, I find out that there is a bit difference in design mode in defining the data context behind the XAML in .cs file like below
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel();
}
}
and doing in a xaml like this.
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
The difference is during design mode in the display window while coding. When the code is in Xaml the view is nice and it shows the elements for eg. for DataGrid its shows the number of rows and column with value its value if its defined.
So, having said that I want to change below code in .cs file to
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
}
its equivalent in XAML. I tried with the below code
<Window.DataContext>
<local:MainWindow/>
</Window.DataContext>
but it throw exception on Initialization. Can someone please help me with it. I am still new to WPF Databindings Data Context stuff.
Thank You
This sets the DataContext to a new instance of MainWindow (which will in turn set the DataContext to a new instance and so on):
<Window.DataContext>
<local:MainWindow/>
</Window.DataContext>
The equivalent of this.DataContext = this would be: <Window ... DataContext="{Binding RelativeSource={RelativeSource Self}}">.
You may also set the design time DataContext:
d:DataContext="{d:DesignInstance Type=local:MainWindow, IsDesignTimeCreatable=True}

WPF/XAML (Window.Resources) cannot find ClassName in NameSpace

I have a problem that I have spent a lot of time to resolve in vain.
I have created a class name in spacename "ComboBoxDGWPF":
public class StatusList : List<string>
{
public StatusList()
{
this.Add("Assigned");
this.Add("Closed");
this.Add("In Progress");
this.Add("Open");
this.Add("Resolved");
}
}
In XAML, I create a staticData like that:
<Window x:Class="ComboBoxDGWPF.Window1"
....
xmlns:staticData="clr-namespace:ComboBoxDGWPF"
....
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<staticData:StatusList x:Key="StatusList"/>
</Window.Resources>
....
</Window> <!-- Added by edit -->
But in XAML it gives me an error:
the name 'StatusList' does not exist in NameSpace 'clr-namespace:ComboBoxDGWPF'.
I'm 100% sure that there is the 'public class StatusList' in that namespace.
I don't understand why this error occurs?
See attached code source for details.

XAML.Parse.Exception on WPF project's deployment

I'm having a problem when I deploy my WPF project, the deployed project crashes on startup and produces a XAML.Parse.Exception with an inner exception of "Cannot have nested BeginInit calls on the same instance" at Line 4 Position 70. The App has full permissions on my computer. I am asking this question because the few questions asked about this had no real solution to the problem.
Here is the XAML code it is referencing with the first couple of lines.
<Window
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" mc:Ignorable="d" x:Class="ASRV.MainWindow"
Title="ASRV GUI" Height="768" Width="1024" ResizeMode="CanMinimize">
<Window.Resources>
</Window.Resources>
<Window.Background>
<ImageBrush ImageSource="pack://siteoforigin:,,,/background.png"/>
</Window.Background>
My guess is the reason being:
<Window.Background>
<ImageBrush ImageSource="pack://siteoforigin:,,,/background.png"/>
</Window.Background>
You might be reusing this image elsewhere in the same window or subcontrol.
BeginInit is called in databinding and this is the only databound thing I could see in your sample code. "BeginInit calls on the same instance" points to it being bound twice.
This error is encountered whenever an object is attempted to be bound twice, as #basarat says in his answer. Further to the example seen in the OP, I came across this same error caused in my case by setting a DataContext in the CodeBehind as well as in the xaml:
In the MainWindow.xaml file, I had the following:
<Window xmlns:vm="clr-namespace:MyApp.ViewModel"
[...more xmlns references skipped for brevity...]
<!--the next three lines caused a problem, when combined with the code behind-->
<Window.DataContext>
<vm:MainViewModel/>
</Window.DataContext>
</Window>
And in the MainWindow.xaml.cs file, I had this:
namespace MyApp.View
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainViewModel MainViewModel { get; set; }
public MainWindow()
{
bool success = false;
MainViewModel = new MainViewModel();
// This line caused the problem in combination with the xaml above
DataContext = MainViewModel;
InitializeComponent();
}
}
}
In order to get rid of the problem, I deleted one of the DataContext setters; it works with either the data context set in xaml or the data cantext set in the code behind, not both.
P.S. I add this answer because this is the first answer to come up on searches for this problem and I felt that further explanation would be useful to other visitors.

How to add UserControl to a Panel on a WPF Window

I think I'm missing something that should be obvious here, but I'm drawing a blank on this one.
I've built a very primitive UserControl containing nothing more than a TextBox to use as a log window:
<UserControl x:Class="My.LoggerControl"
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"
x:Name="LoggerView">
<Grid x:Name="LayoutRoot">
<TextBox x:Name="LogWindow" AcceptsReturn="True"/>
</Grid>
</UserControl>
I don't expect that to be the best way to do it, but it should be good enough for a prototype.
The code-behind is similarly simple:
public partial class LoggerControl : UserControl, ILogger
{
public LoggerControl()
{
InitializeComponent();
}
private LogLevel level = LogLevel.Warning;
#region ILogger
public LogLevel Level
{
get { return level; }
set { level = value; }
}
public void OnError(string s)
{
if (level >= LogLevel.Error)
LogWindow.AppendText("ERROR:::" + s + "\n");
}
// ...
#endregion
}
The thing I can't figure out is how to add this control to my MainWindow.xaml. Simplifying, lets say my window looks like this:
<Window x:Class="My.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:My"
Title="Test" Height="350" Width="525">
<Grid>
<local:LoggerControl x:Name="LogView" />
</Grid>
</Window>
Even with something so simple, the Designer in Visual Studio 2010 can't load the main window. The error given is:
A value of type 'LoggerControl' cannot be added to a collectionor dictionary of type 'UIElementCollection'.
This error message has only one unrelated hit in the major search engines (plus duplicates) so I haven't found any useful help. Microsoft's own documentation seems to imply that this should work.
Any idea how to solve this?
<UserControl x:Class="My.LoggerControl"
xmlns:local="clr-namespace:My.LogTest"
Looks like you may have made a mistake in the namespacing? LoggerControl is listed as being the namespace My, while you're importing My.LogTest and assigning it to the xml-prefix local. Change this to:
xmlns:local="clr-namespace:My"
And I think it should work. Otherwise, fix the LoggerControl declaration.

WPF binding set before application starts does not notify?

In theory this code should provide me with a 300x300 window with a blue background from having the window's content bound to an object of type AstRootViewModel, however this doesn't seem to be the case. I'm wondering it this is happening because I don't call astApplication.Run() until after I set the mainWindow.ViewModel property. Using snoop to check the binding I have a blank content binding and it's flagged as an error with no error information.
If it is the case that property notification does not occurr until the application Run method is called, then what would be the best way to resolve this in an MVVM friendly way?
I have the following Entry point to a WPF application:
[STAThread]
public static void Main()
{
settingsSource = LoadSettingsFile(".\\applicationSettings.xml");
astApplication = new Application();
mainWindow = new AstWindowView();
mainWindowModel = new AstRootViewModel();
dataModel = new AstDataModel(settingsSource);
mainWindow.ViewModel = mainWindowModel;
astApplication.MainWindow = mainWindow;
astApplication.Run();
}
The AstWindowView class implements the following significant code behind:
public partial class AstWindowView : Window
{
public AstRootViewModel ViewModel
{
get { return (AstRootViewModel)GetValue(ViewModelProperty); }
set { SetValue(ViewModelProperty, value); }
}
// Using a DependencyProperty as the backing store for ViewModel. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ViewModelProperty =
DependencyProperty.Register("ViewModel", typeof(AstRootViewModel), typeof(Window), new UIPropertyMetadata(null));
public AstWindowView()
{
InitializeComponent();
}
}
and the following significant XAML
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="AstViewResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Window.Content>
<Binding Path="ViewModel" Mode="Default" UpdateSourceTrigger="PropertyChanged"/>
</Window.Content>
The AstViewResources.xaml file defines the following DataTemplate
<DataTemplate DataType="{x:Type vm:AstRootViewModel}">
<vw:AstRootView/>
</DataTemplate>
And lastly, the AstRootView XAML contains the following significant XAML:
<UserControl x:Class="SEL.MfgTestDev.AutomatedSettingsTransfer.View.AstRootView"
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 Background="#FF000CFF"/>
</UserControl>
It looks like you're not setting the DataContext for AstWindowView anywhere and your Binding has no explicit Source set. Are you seeing a binding error saying something to that effect in your debug output? Try adding after the InitializeComponent call in AstWindowView ctor (could also do it by changing the Binding in XAML):
DataContext = this;

Resources