How to access WPF MainWindow Controls from my own .cs file - c#

I am a NOVICE and am very much struggling with what seems should be a very simple task. How do I modify a property of a MainWindow TextBlock, from another cs file. An exact code solution would be extremely helpful.
Below is the stripped down code. Is my use of static class causing me extra issues?
In File: MainWindow.xaml
<Window x:Class="TestApp1.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">
<Grid>
<TextBlock x:Name="TextBlock1" HorizontalAlignment="Left" Margin="107,71,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top"/>
</Grid>
</Window>
In File: MainWindow.xaml.cs
namespace TestApp1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
TextBlock1.Text = "Setting Text from MainWindow";
MyProgram.myProgramStart();
}
}
}
In File: CodeFile1.cs
namespace TestApp1
{
public static class MyProgram
{
public static void myProgramStart()
{
// ... blah blah blah
// I want to do something like follows, but won't compile
MainWindow.TextBlock1.Text = "Setting Text from My Program";
}
}
}

Because nobody else has actually answered the question I'm going to tell you how to achieve what you want, but do listen to the posters who said that in a real application you would use MVVM. However there are times when you need to do what you ask so the code you need is:
((MainWindow)System.Windows.Application.Current.MainWindow).TextBlock1.Text = "Setting Text from My Program";

You can simply achieve this using MVVM. You shouldn't directly access controls in View using its name from another class. You have to use binding properties.
First of all, add a class. This will be your ViewModel. Add your properties to this class which will be binded to your input controls in your View.
Student ViewModel
public class Student
{
public string Name
{
get { return "Setting Text from My Program"; }
}
}
App.Config
Now you have add to this View Model as a resource in your App.Config file. First, add the name space reference to your app.config where your VM resides.
[xmlns:local="clr-namespace:WpfApplication2]. Add your VM class as a resource by specifying your View Model class name (student).
<Application x:Class="WpfApplication2.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
xmlns:local="clr-namespace:WpfApplication2">
<Application.Resources>
<local:Student x:Key="Student" />
</Application.Resources>
</Application>
MainWindow.xaml
Set the DataContext with the resource key added to App.config and set the binding to the property defined in the Student View Model.
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DataContext="{StaticResource Student}"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBlock Text="{Binding Name}" Height="23" HorizontalAlignment="Left" Margin="127,124,0,0" Name="textBlock1" VerticalAlignment="Top" Width="214" />
</Grid>
</Window>

Basically there are more than 2-3 methods. Given method is quite easier to understand & handle.
You can access MainWindow controls by following codes (1),(2),(3),(4).
In File: MainWindow.xaml.cs
public partial class MainWindow
{
internal static MainWindow Main; //(1) Declare object as static
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Main =this; //(2) Defined Main (IMP)
var AnyClassORWindow=new Class1(); //Initialize another Class
AnyClassORWindow.ShowValue();
}
}
In File: Class1.cs
internal class Class1 : MainWindow //(3) Inherited
{
internal void Display()
{
MessageBox.Show(Main.TextBox1.Text); //(4) Access MainWindow Controls by adding 'Main' before it.
}
}
Notes:-
It's good practice to use code (2) after window LOADED not in CONSTRUCTOR.
Code (2) in constructor may leave run-time problems.
Another simple method is to use 'ref MainWindow_field' by passing to each class's Constructor OR assign '(MainWindow) Application.Current.MainWindow' to static Main.

Use MVVM pattern to access properties of the control and modify them:
public class Student
{
public Student()
{
}
public string Name
{
get { return "Setting Text from My Program"; }
}
}
Set the DataContext of the XAML in the code behind:
this.DataContext = new Student();
Bind the Text property to Name:
<TextBlock Text="{Binding Name}"/>

As for why it won't compile, I will assume the compiler error you are getting is...
An object reference is required for the non-static field, method, or property 'TestApp1.MainWindow.TextBlock1'
This happens because you are trying to access an TextBlock1 as if it were static. As #JeffRSon stated, create an instance of your MainWindow class first.
// Create an instance of MainWindow
var mainWindow = new MainWindow();
mainWindow.TextBlock1.Text = "Setting Text from My Program";
I assume you may want to display the window as well...
mainWindow.ShowDialog();

You need to create an instance of MainWindow.
But there shouldn't be a reason to do that because it will be done automagically in an WPF app. Unless you have specific reason to do that (which I doubt because of this question and because you say you're a novice).

To extend on what Nathan said, I used a safe cast:
(System.Windows.Application.Current.MainWindow as MainWindow)?.TextBlock1.Text = "Setting Text from My Program";
Note the comments on the answer Nathan gave. This isn't ideal but it works.

you can use App.Current.MainWindow anywhere in your app :)
You should also use the FindChild method to find your component ...
MyProgram.cs :
public static class MyProgram
{
public static void myProgramStart()
{
// ... blah blah blah
// I want to do something like follows, but won't compile
//MainWindow.TextBlock1.Text = "Setting Text from My Program";
var tb = FindChild3<TextBlock>(App.Current.MainWindow, "TextBlock1");
tb.Text = "Setting Text from My Program";
}
public static T FindChild3<T>(DependencyObject depObj, string childName)
where T : DependencyObject
{
// Confirm obj is valid.
if (depObj == null) return null;
// success case
if (depObj is T && ((FrameworkElement)depObj).Name == childName)
return depObj as T;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
//DFS
var obj = FindChild3<T>(child, childName);
if (obj != null)
return obj;
}
return null;
}
}
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
MyProgram.myProgramStart();
}
}
This trick worked for me :)
GoodLuck ✌️

Related

WPF view who leads to another using MVVM

I am trying to set up a navigation between views using a MVVM pattern. My application contains a MainWindow and two views with a button each. When I click on the button in the View1 I want to set up the View2 on the MainWindow.
I have found several tutorials witch explain how to navigate from a view to another with a button on the main window (simulate a tabControl), it works but it is not what I want.
I'm looking for something like :
View1_View.xaml.cs :
public partial class View1_View : UserControl
{
private View1_ViewModel _viewModel = new View1_ViewModel();
public View1_View()
{
InitializeComponent();
}
private void Btn_SwitchToView2_Click(object sender, RoutedEventArgs e)
{
MainWindow.SwitchToView2();
}
}
MainWindow.xaml.cs :
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new View1_View();
}
public void SwitchToView2()
{
this.DataContext = new View2_View();
}
}
My problem is if I do so, from the class View1_View I cannot access to the method SwitchToView2() if it is not static, and if it is static I lose the context of the MainWindow.
How should I proceed ?
Thanks.
I would recommend using a ContentControl to switch the part of your main view.
This could look like this (short form just to give you an idea; without INotifyPropertyChanged).
Create an empty interface of type ISwitchableViewModel.
Add a property to your main ViewModel
public property ISwitchableViewModel MyViewModel {get; set;}
Create two classes that implements the interface ISwitchableViewModel. Each for each view you want to show (View1 and View2 in your example) and call them ViewModel1 and ViewModel2.
When you press the button in your xaml set the MyViewModel to View1 or View2; whatever your logic is.
In your xaml add this at the place where you want to show the switchable content.
<ContentControl Content="{Binding MyViewModel}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type viewModel:ViewModel1}">
<view:View1 />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModel:ViewModel2}">
<view:View2 />
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
When you set the MyViewModel in your MainViewModelthe UI will show automatically the correct view for that viewmodel.
You can achieve this by creating the views and assigning them to a content control.
Lets assume you have this content control in your main view.
<Window x:Class="MVVM.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:MVVM"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<Button x:Name="ChangeView" Click="SwitchToSecondView" Content="Set View"></Button>
<ContentControl x:Name="MainContent"></ContentControl>
</StackPanel>
</Window>
You can then set the content in the code behind file of your main view.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public void SwitchToSecondView(object sender, outedEventArgs e)
{
var view = new SecondView();
var model = new SecondViewModel(this);
view.DataContext = model;
MainContent.Content = view;
}
public void SwitchToThirdView(object sender, outedEventArgs e)
{
var view = new ThirdView();
var model = new ThirdViewModel(this);
view.DataContext = model;
MainContent.Content = view;
}
}
Another solution would be to use an MVVM Framework light Caliburn.Micro, Prism etc, which essential do the same thing as the code snippet above, but hide the boilerplate code.
EDIT: I realized i didn't explicitly get to the second part of your question.
Usally one would need some kind of router which is able to control the navigation. For the sake of simplicity we use the main view as router. To access the main view, you need to inject it in each component.
This allows each of your submodels to access the main view.
This could be improved by using some kind of DI-Container or by a Mediator. A mediator would allow each component to send requests, which then are dispatched to the MainView, eliminating the direct dependency.

Cannot Create custom command in WPF Application

Overview
I have a WPF application written in C# .NET 4.0. There are a number of buttons in this project. Currently, every EventHandler for the button click events calls the same method, with a different valued parameter. As this is all done in C# code, it is rather unwieldy and involves a lot of copy/paste.
I'd much rather use a Command, rather than a bunch of EventHandlers, as it keeps my code cleaner.
Problem
No matter what I do, I cannot get the XAML to accept the new command:
<Window.CommandBindings>
<CommandBinding Command="ButtonClick" Executed="ButtonClick_Executed" />
</Window.CommandBindings>
The above code has an error: "CommandConverter cannot convert from System.String". This error exists on the Command="ButtonClick".
Research/Attempts
I've tried everything I can think of to make this work to no avail. I've looked at at least 30 different blog posts/tutorials/etc. on how to properly do this, so I don't have an actual list for you. I saw some people using the Binding keyword, so I attempted: Command="{Binding ButtonClick}", but apparently that's not allowed inside a CommandBinding section. I have also tried Command="{x:Static ButtonClick}", but that doesn't work either.
As for the "ButtonClick" itself, I have tried several possible values there. "ButtonClick" is an arbitrary text string that does not correspond to any class/method/variable. My original understanding of this parameter was for the value to be simply an identifying string. I have also tried using an actual method in the same class "ButtonClick_Executed". I have also tried using a class name which implements ICommand (Commands), as well as a method inside that class (Commands.ButtonClick_Executed).
For reference, I also tried doing this in the codebehind as per WPF: Binding to commands in code behind, but I couldn't make that work either.
Code
Code is abridged to what is relevant. From what I understand, the Button's Command parameter needs to match the CommandBinding's Command value. I have not added this in yet, since I can't even get the CommandBinding to work. All code is in the same namespace, in a single project.
MainWindow.xaml:
<Window x:Class="T9Messager.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="600" Width="540">
<Window.CommandBindings>
<CommandBinding Command="ButtonClick" Executed="ButtonClick_Executed" />
</Window.CommandBindings>
<Grid Margin="0,0,0,0">
<Button x:Name="Button1" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="165" Height="113">
<TextBlock HorizontalAlignment="Center" TextAlignment="Center" FontSize="18" FontWeight="Bold">1</TextBlock>
</Button>
... More buttons ...
</Grid>
</Window>
MainWindow.xaml.cs:
public partial class MainWindow : Window, IObserver<Model>
{
private Controller controller;
private IDisposable Unsubscriber;
public MainWindow()
{
Model model = new Model();
Controller controller = new Controller(model);
this.controller = controller; // MainWindow view = new MainWindow(c);
Unsubscriber = model.Subscribe(this);
InitializeComponent();
}
// This is the method I want to run
public void ButtonClick_Executed(object sender, EventArgs ev)
{
Console.WriteLine("Command Executed");
}
// I want to avoid having a bunch of these
private void Button_Click_1(object sender, RoutedEventArgs e)
{
controller.HandleButtonClick('1');
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
controller.HandleButtonClick('2');
}
... More ButtonClick Events ...
public void OnCompleted()
{
Unsubscriber.Dispose();
}
public void OnError(Exception error)
{
throw new NotImplementedException();
}
public void OnNext(Model value)
{
tb_text.Text = value.text;
}
}
Commands.cs:
public class Commands : ICommand
{
public Commands()
{
CommandBinding ButtonClickBinding = new CommandBinding(ButtonClickCommand);
CommandManager.RegisterClassCommandBinding(typeof(Commands), ButtonClickBinding);
}
private RoutedUICommand ButtonClick = new RoutedUICommand("ButtonClick", "ButtonClick", typeof(Commands));
public RoutedCommand ButtonClickCommand
{
get { return ButtonClick; }
}
// Getting any of the following 3 methods to execute would be fine
public static void test()
{
}
public void Execute(object parameter)
{
ButtonClick_Executed(null, null);
}
public void ButtonClick_Executed(object sender, EventArgs ev)
{
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
}
Any and all help is greatly appreciated. Please let me know if you require any additional information.
Update
I have attempted the answer proposed by Herdo. The new error I got was The namespace prefix "T9Messager" is not defined. After research, my XAML now opens like this:
<Window x:Class="T9Messager.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:T9Messager="clr-namespace:T9Messager"
Title="MainWindow" Height="600" Width="540">
This seems to have fixed that particular issue, but now it looks as if the XAML is completely ignoring the Command parameter. Command="T9Messager:Commands.ButtonClick" creates the error Value cannot be null. Parameter name: value.
This ButtonClick is a String:
<CommandBinding Command="ButtonClick" Executed="ButtonClick_Executed" />
You need to write it as a member of the class (note that you need to add the namespace in the window declaration):
<Window xmlns:t9m="clr-namespace:T9Messager"
...>
<CommandBinding Command="t9m:Commands.ButtonClick"
Executed="ButtonClick_Executed" />
In my code, I removed the "x:Static" from 'Command="{x:Static ButtonClick}"' and worked.

Creating a single controller for multiple WPF Pages

I'm very new to WPF and a beginner in C#.NET. I'm currently making an application where there will be many pages and the trigger to change the page is hand gesture using Kinect SDK (the trigger method is not relevant for this question). Normally when a WPF file is created, there will be a similarly named .cs file attached to it, which acts somewhat like a controller. However, I need multiple WPF files/pages to be controlled only by a single controller .cs file. How do I achieve that? Thanks for viewing my question and your answer will be very appreciated :)
You probably want to write a class that contains your 'controller' code and reference it from your WPF UserControls / Pages.
In a new file:
public class MyController
{
public void DoThings(object parameter)
{
// stuff you want to do
}
}
and then inside your UserControl code-behind class:
public partial class MyWpfControl : UserControl
{
private MyController controller;
public MyWpfControl
{
this.controller = new MyController();
}
}
and finally, tie your events back to the controller's method:
private void OnGesture(object sender, EventArgs e)
{
// call the method on the controller, and pass whatever parameters you need...
this.controller.DoThings(e);
}
The code behind is really part of the view and isn't really analogous to a controller and generally there shouldn't be much code in them. Typically you would want most of your logic between your "View Model" which serves as an abstraction of the view and "Model" which serves as an abstraction of the business logic that your UI is interacting with.
In this light what I think you really want is a View Model(VM) that controls multiple views. This is a fairly typical scenario and the preferred method (IMO anyway) is to have a hierarchical view model that has a top level the application model and a number of sub VMs that represent different components within your UI, though you can bind everything to your top level VM if you really want to.
To do this we would first define our view model like so
public interface IGestureSink
{
void DoGesture();
}
public class MyControlVM : INotifyPropertyChanged, IGestureSink
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
private ApplicationVM parent;
public MyControlVM(ApplicationVM parent)
{
this.Name = "my user control";
this.parent = parent;
parent.PropertyChanged += (s, o) => PropertyChanged(this, new PropertyChangedEventArgs("Visible"));
}
public String Name { get; set; }
public bool Visible { get { return parent.ControlVisible; } }
public void DoGesture()
{
parent.DoGesture();
}
}
public class ApplicationVM : INotifyPropertyChanged, IGestureSink
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
public ApplicationVM()
{
this.ControlVM = new MyControlVM(this);
this.ControlVisible = false;
}
public MyControlVM ControlVM { get; private set; }
public bool ControlVisible {get; set;}
public void DoGesture()
{
this.ControlVisible = !this.ControlVisible;
PropertyChanged(this, new PropertyChangedEventArgs("ControlVisible"));
}
}
and then all we need to do is to build a user control
<UserControl x:Class="WpfApplication2.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid Background="LightBlue">
<Label Content="{Binding Name}"/>
</Grid>
</UserControl>
and page
<Window xmlns:my="clr-namespace:WpfApplication2" x:Class="WpfApplication2.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">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
<Grid>
<my:MyControl Width="200" Height="200" x:Name="myUserControl" DataContext="{Binding ControlVM}" Visibility="{Binding Visible,Converter={StaticResource BooleanToVisibilityConverter}}"/>
<Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="222,262,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
</Grid>
</Window>
That use it. The only thing that we need in our code behind is a constructor that sets up the page VM and wiring from our button to the view model.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new ApplicationVM();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
((IGestureSink)(this.DataContext)).DoGesture();
}
}
If you wanted to use a monolithic view model instead you would use this Instead of binding the DataContext to ControlVM:
<my:MyControl Width="200" Height="200" x:Name="myUserControl" DataContext="{Binding DataContext}" Visibility="{Binding ControlVisible,Converter={StaticResource BooleanToVisibilityConverter}}"/>

Help with WPF data binding

I'm new to WPF and I'm trying to figure out how data binding works, but I'm not having much luck.
I'm trying to start with something simple - binding the contents of a text box to a string variable in my program.
I read lots and lots of pages of MSDN documentation about data binding, XML namespaces, markup extensions, resources, dependency properties and whatnot, and I'm still not able to get it to work.
Here's my MainWindow.xaml:
<Window x:Class="WpfTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:WpfTest"
Title="MainWindow">
<Grid>
<Grid.Resources>
<c:Foo x:Key="MyFoo"/>
</Grid.Resources>
<TextBox Width="100" Height="28"
Text="{Binding Source=MyFoo,
Path=BarProperty,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</Window>
And my MainWindow.xaml.cs:
namespace WpfTest
{
public class Foo : DependencyObject
{
public static readonly DependencyProperty BarProperty = DependencyProperty.Register("Bar", typeof(String), typeof(Foo));
public String Bar
{
get { return (String)GetValue(BarProperty); }
set { SetValue(BarProperty, value); }
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
MyFoo = new Foo { Bar = "hello" };
}
public Foo MyFoo { get; set; }
}
}
I would expect the text box to show "hello" when the program starts up, but it is empty.
Can someone tell me what I am doing wrong?
You need to set the DataContext of your Window to itself.
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
MyFoo = new Foo { Bar = "hello" };
}
This tells WPF to look for bindings within your class.
Every control can set a DataContext which says "when I bind, I want to bind to a property on this specific instance... This is inherited, so if you set the DataContext of the MainWindow to itself, all controls inside of MainWindow will bind to properties on the MainWindow.
You need to specify the source. Either:
Give the window a name like Name="mywin", alter your binding witn ElementName="myWin"
Or set the window DataContext like:
DataContext="{Binding ElementName="myWin"} - you can also use a RelativeSource if you don't want the name I just couldn't post it untested - Bindings tend to require testing as you also noticed :)
This might help:
http://blogs.msdn.com/b/wpfsdk/archive/2006/10/19/wpf-basic-data-binding-faq.aspx

C# WPF Binding Behavior

I am a reasonably experienced programmer but new to WPF. I have bound a textblock on a form to an object property, but it is not updating the form as I would expect when I set the property. The binding appears to be done correctly--if I troubleshoot with a button that updates the property the form changes, but when I initially set the property in the form's constructor by parsing a local XML file it doesn't update.
I am using C# and VS2010. Could someone guide me for a few steps or refer me to a book or coding tool that gets me over this hump. Also, please note that I chose to structure things way by imitating the paradigm used in the "How Do I: Build My First WPF Application" at windowsclient.net. If you think I'm going about it the wrong way, I would appreciate a pointer to a better tutorial.
Form XAML:
<Window ...
xmlns:vm="clr-namespace:MyProjectWPF.ViewModels">
<Grid>
<Grid.DataContext>
<vm:MyConfigurationViewModel />
</Grid.DataContext>
<TextBlock Name="textBlock4" Text="{Binding Path=Database}" />
</Grid>
MyConfigurationViewModel class definition:
class MyConfigurationViewModel : INotifyPropertyChanged
{
private string _Database;
public string Database
{
get { return _Database; }
set { _Database = value; OnPropertyChanged("Database"); }
}
public void LoadConfiguration()
{
XmlDocument myConfiguration = new XmlDocument();
myConfiguration.Load("myfile.xml");
XmlNode root = myConfiguration.DocumentElement;
Database = root["Database"].InnerText;
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string Property)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(Property));
}
And the codebehind my XAML form:
public partial class MyForm : Window
{
private ViewModels.myConfigurationViewModel mcvm
= new ViewModels.myConfigurationViewModel();
public MyForm()
{
mcvm.LoadConfiguration();
}
You have two instances of myConfigurationViewModel. One is created inside the XAML and the second one is created inside the form's codebehind. You are calling LoadConfiguration on the one in the code behind, which is never set as the form's DataContext.
Remove this from the XAML:
<Grid.DataContext>
<vm:MyConfigurationViewModel />
</Grid.DataContext>
and change the constructor to this:
public MyForm()
{
mcvm.LoadConfiguration();
DataContext = mcvm;
}
Can you try this XAML:
<Window ...
xmlns:vm="clr-namespace:MyProjectWPF.ViewModels">
<Grid>
<TextBlock Name="textBlock4" Text="{Binding Path=Database}" />
</Grid>
with this code:
public partial class MyForm : Window
{
private ViewModels.myConfigurationViewModel mcvm = new ViewModels.myConfigurationViewModel();
public MyForm()
{
mcvm.LoadConfiguration();
this.DataContext = mcvm;
}
[Update] Was wrong on the explanation, removed it.

Categories