I am having trouble accessing my ViewModel when working with my view.
I have a project named BankManagerApplication. Within that I have the various files associated with a new WPF application. I have created three seperate folders Model, ViewModel and View.
At the moment there is a UserModel class in the Model folder with the following fields;
namespace BankManagerApplication.Model
{
public class UserModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public double AccountBallance { get; set; }
}
}
a blank view in the View folder with just a grid inside;
<Window x:Class="BankManagerApplication.View.MainWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindowView" Height="300" Width="300">
<Grid>
</Grid>
</Window>
and also a blank ViewModel in the ViewModel folder;
namespace BankManagerApplication.ViewModel
{
public class MainWindowViewModel
{
}
}
when i try to reference the ViewModel in my XAML like so;
<Window x:Class="BankManagerApplication.View.MainWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindowView" Height="300" Width="300"
xmlns:viewmodel="clr-namespace:BankManagerApplication.ViewModel">
<Grid>
<viewmodel:MainWindowViewModel></viewmodel:MainWindowViewModel>
</Grid>
</Window>
i get the error
The name 'MainWindowViewModel does not exist in the namespace
"clr-namespace:BankManagerApplication.ViewModel'
I have only just started learning WPF and this error is throwing me off before I have really begun
You cannot add it to a Grid control because it is not a UIElement. Your viewmodel will be the DataContext of your view:
<Window x:Class="BankManagerApplication.View.MainWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindowView" Height="300" Width="300"
xmlns:viewmodel="clr-namespace:BankManagerApplication.ViewModel">
<Window.DataContext>
<viewmodel:MainWindowViewModel></viewmodel:MainWindowViewModel>
</Window.DataContext>
<Grid>
</Grid>
Related
In a user control I have context menu for data grid like shown below
<DataGrid.ContextMenu>
<ContextMenu Focusable="False">
<menuItems:ExportMenuItemView DataContext="{Binding ExportMenuItemVM}"/>
</ContextMenu>
</DataGrid.ContextMenu>
in the view model class I have the view property
public ExportMenuItemViewModel ExportMenuItemVM {get;set;}
ExportMenuItemView is a user control which contains a menu item
<UserControl x:Class="MenuControl.View.ExportMenuItemView"
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="20" d:DesignWidth="200">
<MenuItem Header="Export" Focusable="False" Command="{Binding Export}"/>
</UserControl>
Below is the view model class for the Export View
namespace MenuControl.ViewModel
{
[AddINotifyPropertyChangedInterface]
public class ExportMenuItemViewModel : ViewModelBase
{
public ExportBlockMenuItemViewModel(IExport exporter)
{
Export = new RelayCommand(() => exporter.Export());
}
public RelayCommand Export { get; set; }
}
}
RelayCommand Export is not getting executed when I click the menu item "Export". I am using MVVLLight
I think you are missing something related to the DataContext Binding in your xaml like :
<UserControl x:Class="MenuControl.View.ExportMenuItemView"
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="20" d:DesignWidth="200"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<MenuItem Header="Export" Focusable="False" Command="{Binding Export}"/>
</UserControl>
ViewModels in ViewModelLocator MVVM Light
Found solution
I need to create a separate function. If I call the operation as a lambda function as shown below, it is not working
Export = new RelayCommand(() => exporter.Export());
I need to create a function "foo" and give that in the relay command like shown below. I do know the reason but when I change the code as below, it started working
Export = new RelayCommand(foo);
private void foo()
{
exporter.Export()
}
I am working on desktop app in WPF and I want to follow the MVVM pattern. I have my view ready and it was time to do a viewmodel. But for some reason i can't bind viewmodel to the view.
I have tried this in XAML of the view:
<Window x:Class="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:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
mc:Ignorable="d"
Title="" Height="626" Width="1200" Background="#FFDEDF1A"
DataContext="ViewModels/MainViewModel">
Didn't work so i tried this in the class of View:
public MainWindow()
{
this.DataContext = new MainViewModel();
InitializeComponent();
}
But it doesn't work either... I tried to look it up on the internet but everyone is doing the same thing.
ViewModel:
class MainViewModel : INotifyPropertyChanged
{
public string BindingTest { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
public MainViewModel()
{
BindingTest = "test";
}
}
And how I binded the property:
<TextBlock Text="{Binding Path= BindingTest}" Padding="10"/>
This is how my files look:
If you want to set the DataContext in XAML, you should do something like this:
<Window x:Class="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:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:viewModels="clr-namespace:AssemblyName.ViewModels"
mc:Ignorable="d"
Title="" Height="626" Width="1200" Background="#FFDEDF1A">
<Window.DataContext>
<viewModels:MainViewModel />
</Window.DataContext>
<!-- Your Code Here... -->
</Window>
Change the AssemblyName to your project name.
I have one dll which contains the wpf user control.
I have one wpf window in another wpf project which contains the above user control in that.
I have two public properties in wpf user control.
I want to set those properties from the wpf window in which wpf user control is added.
I have tried to do it using dependency property as follows :
TestUserControl.xaml :-
<UserControl x:Class="TestDependencyProperty.TestUserControl"
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>
<Label Content="test property" x:Name="lblTestProperty"/>
</Grid>
</UserControl>
TestUserControl.xaml.cs :-
using System.ComponentModel;
using System.Windows;
namespace TestDependencyProperty
{
/// <summary>
/// Interaction logic for TestUserControl.xaml
/// </summary>
public partial class TestUserControl
{
public TestUserControl()
{
InitializeComponent();
SetLabelText();
}
private void SetLabelText()
{
lblTestProperty.Content = TestProperty;
}
public static readonly DependencyProperty TestDependencyProperty =
DependencyProperty.Register("TestProperty",
typeof(string),
typeof(TestUserControl));
[Bindable(true)]
public string TestProperty
{
get
{
return (string)this.GetValue(TestDependencyProperty);
}
set
{
this.SetValue(TestDependencyProperty, value);
}
}
}
MainWindow.xaml :-
<Window x:Class="TestDependencyProperty.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:local="clr-namespace:TestDependencyProperty"
>
<Grid>
<local:TestUserControl x:Name="ucTest" TestProperty="HelloWorld"/>
</Grid>
</Window>
I am expecting a label with content "HelloWorld".
So can anybody tell me how to do it ?
Thanks.
User Control XAML:
<UserControl x:Class="TestDependencyProperty.TestUserControl"
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:WpfApplication3"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Label Content="{Binding TestProperty}" x:Name="lblTestProperty"/>
</Grid>
</UserControl>
User Control Code:
public partial class TestUserControl : UserControl
{
public TestUserControl()
{
InitializeComponent();
}
public static readonly DependencyProperty TestDependencyProperty =
DependencyProperty.Register("TestProperty",
typeof(string),
typeof(TestUserControl));
[Bindable(true)]
public string TestProperty
{
get
{
return (string)this.GetValue(TestDependencyProperty);
}
set
{
this.SetValue(TestDependencyProperty, value);
}
}
}
You do not need SetLabelText();
Window Hosting User Control
<local:TestUserControl TestProperty="Test Text" x:Name="MyNewUserControl" />
in code behind if needed:
MyNewUserControl.TestProperty="New Value";
Dependency Properties have change notification built in to them so once a property is bound to them it will automatically get updated when the property does.
I can't figure out what I'm doing wrong in this most trivial example. How do I create a resource that references a public class in the local namespace of my project?
In MainWindow.xaml:
<Window x:Class="Foo.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:Foo"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.Resources>
<local:Bar x:Key="MyBar" /><!-- problem here -->
</Grid.Resources>
</Grid>
</Window>
In MainWindow.xaml.cs:
namespace Foo
{
public class Bar
{
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
When I do this, I get the error The name "Bar" does not exist in the namespace "clr-namespace:Foo".
This question is almost identical to this related question but my class is already public.
Just build the project, it should work, it's correct.
Try to to inherit your class from UserControl
public class Bar : UserControl
{
}
https://msdn.microsoft.com/en-us/library/ms753379.aspx
I have been trying to bind listpickerflyout to some data and it doesn't seem to display the data when I debug.
Here is the XAML Code:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App6"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ViewModel="using:App6.ViewModel"
xmlns:Model="using:App6.Model"
x:Class="App6.MainPage"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page.DataContext>
<ViewModel:MainViewModel/>
</Page.DataContext>
<Grid>
<Button Margin="10,0,0,583" Width="313">
<Button.Flyout>
<ListPickerFlyout ItemsSource="{Binding Language.Name}"/>
</Button.Flyout>
<Button.DataContext>
<Model:Language/>
</Button.DataContext>
</Button>
</Grid>
And the other codes MVVM model:
namespace App6.Model
{
public class Language
{
public string Name { get; set; }
public int id { get; set; }
}
}
viewmodel:
namespace App6.ViewModel
{
public class MainViewModel
{
public Language Language { get; set; }
public MainViewModel()
{
Language = new Language
{
Name = "English",
id = 1
};
}
}
}
You are assigning an object of type "Language" to the datacontext of the button. Therefore the Binding Path is wrong as "Language" does not have a property "Language".
You should create an instance of your viewmodel and assign it to the datacontext of the window. No assignment on the button.