WPF DataBinding not updating? - c#

I have a project, where I bind a checkbox's IsChecked property with a get/set in the codebehind. However, when the application loads, it doesn't update, for some reason. Intrigued, I stripped it down to its basics, like this:
//using statements
namespace NS
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private bool _test;
public bool Test
{
get { Console.WriteLine("Accessed!"); return _test; }
set { Console.WriteLine("Changed!"); _test = value; }
}
public MainWindow()
{
InitializeComponent();
Test = true;
}
}
}
XAML:
<Window x:Class="TheTestingProject_WPF_.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" DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<Viewbox>
<CheckBox IsChecked="{Binding Path=Test, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Viewbox>
</Grid>
And, lo and behold, when I set it to true, it did not update!
Anyone can come up with a fix, or explain why?
Thanks, it'd be appreciated.

In order to support data binding, your data object must implement INotifyPropertyChanged
Also, it's always a good idea to Separate Data from Presentation
public class ViewModel: INotifyPropertyChanged
{
private bool _test;
public bool Test
{ get { return _test; }
set
{
_test = value;
NotifyPropertyChanged("Test");
}
}
public PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
<Window x:Class="TheTestingProject_WPF_.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>
<Viewbox>
<CheckBox IsChecked="{Binding Path=Test, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Viewbox>
</Grid>
Code Behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel{Test = true};
}
}

Related

WPF Usercontrol Bindings with MVVM ViewModel not working

I've spent some time trying to solve this problem but couldn't find a solution.
I am trying to bind commands and data inside an user control to my view model. The user control is located inside a window for navigation purposes.
For simplicity I don't want to work with Code-Behind (unless it is unavoidable) and pass all events of the buttons via the ViewModel directly to the controller. Therefore code-behind is unchanged everywhere.
The problem is that any binding I do in the UserControl is ignored.
So the corresponding controller method is never called for the command binding and the data is not displayed in the view for the data binding. And this although the DataContext is set in the controllers.
Interestingly, if I make the view a Window instead of a UserControl and call it initially, everything works.
Does anyone have an idea what the problem could be?
Window.xaml (shortened)
<Window x:Class="Client.Views.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:Client.Views"
mc:Ignorable="d">
<Window.Resources>
<local:SubmoduleSelector x:Key="TemplateSelector" />
</Window.Resources>
<Grid>
<StackPanel>
<Button Command="{Binding OpenUserControlCommand}"/>
</StackPanel>
<ContentControl Content="{Binding ActiveViewModel}" ContentTemplateSelector="{StaticResource TemplateSelector}">
<ContentControl.Resources>
<DataTemplate x:Key="userControlTemplate">
<local:UserControl />
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</Grid>
</Window>
MainWindowViewModel (shortened)
namespace Client.ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
private ViewModelBase mActiveViewModel;
public ICommand OpenUserControlCommand { get; set; }
public ViewModelBase ActiveViewModel
{
get { return mActiveViewModel; }
set
{
if (mActiveViewModel == value)
return;
mActiveViewModel = value;
OnPropertyChanged("ActiveViewModel");
}
}
}
}
MainWindowController (shortened)
namespace Client.Controllers
{
public class MainWindowController
{
private readonly MainWindow mView;
private readonly MainWindowViewModel mViewModel;
public MainWindowController(MainWindowViewModel mViewModel, MainWindow mView)
{
this.mViewModel = mViewModel;
this.mView = mView;
this.mView.DataContext = mViewModel;
this.mViewModel.OpenUserControlCommand = new RelayCommand(ExecuteOpenUserControlCommand);
}
private void OpenUserControlCommand(object obj)
{
var userControlController = Container.Resolve<UserControlController>(); // Get Controller instance with dependency injection
mViewModel.ActiveViewModel = userControlController.Initialize();
}
}
}
UserControlSub.xaml (shortened)
<UserControl x:Class="Client.Views.UserControlSub"
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:Client.Views"
xmlns:viewModels="clr-namespace:Client.ViewModels"
mc:Ignorable="d">
<Grid>
<ListBox ItemsSource="{Binding Models}" SelectedItem="{Binding SelectedModel}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Attr}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel>
<Button Command="{Binding Add}">Kategorie hinzufügen</Button>
</StackPanel>
</Grid>
</UserControl>
UserControlViewModel (shortened)
namespace Client.ViewModels
{
public class UserControlViewModel : ViewModelBase
{
private Data _selectedModel;
public ObservableCollection<Data> Models { get; set; } = new ObservableCollection<Data>();
public Data SelectedModel
{
get => _selectedModel;
set
{
if (value == _selectedModel) return;
_selectedModel= value;
OnPropertyChanged("SelectedModel");
}
}
public ICommand Add { get; set; }
}
}
UserControlController (shortened)
namespace Client.Controllers
{
public class UserControlController
{
private readonly UserControlSub mView;
private readonly UserControlViewModel mViewModel;
public UserControlController(UserControlViewModel mViewModel, UserControlSub mView)
{
this.mViewModel = mViewModel;
this.mView = mView;
this.mView.DataContext = mViewModel;
this.mViewModel.Add = new RelayCommand(ExecuteAddCommand);
}
private void ExecuteAddCommand(object obj)
{
Console.WriteLine("This code gets never called!");
}
public override ViewModelBase Initialize()
{
foreach (var mod in server.GetAll())
{
mViewModel.Models.Add(mod);
}
return mViewModel;
}
}
}

WPF - MVVM - UserControl binding

I'm trying to realize a simple example of a UserControl, showing in a TextBox the current DateTime, updated four times each second.
I create a simple user control:
<UserControl x:Class="UC.TestUC"
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:UC"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="100">
<d:UserControl.DataContext>
<local:TestUC_VM/>
</d:UserControl.DataContext>
<Grid Background="Azure">
<TextBox Text="{Binding TestString}"/>
</Grid>
</UserControl>
Where its ViewModel is:
namespace UC
{
public class TestUC_VM : INotifyPropertyChanged
{
private string _testString;
public string TestString
{
get => _testString;
set
{
if (value == _testString) return;
_testString = value;
OnPropertyChanged();
}
}
public TestUC_VM()
{
TestString = "Test string.";
}
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
MainWindow XAML:
<Window x:Class="UC.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:UC"
mc:Ignorable="d"
Title="MainWindow" Height="100" Width="200">
<Window.DataContext>
<local:MainWindow_VM/>
</Window.DataContext>
<Window.Resources>
<local:TestUC_VM x:Key="TestUC_VM"/>
</Window.Resources>
<Grid>
<local:TestUC DataContext="{StaticResource TestUC_VM}"/>
</Grid>
</Window>
And its ViewModel:
namespace UC
{
public class MainWindow_VM
{
public TestUC_VM _uc_VM;
public MainWindow_VM()
{
_uc_VM = new TestUC_VM();
Task.Run(() => ChangeString());
}
public async Task ChangeString()
{
while (true)
{
_uc_VM.TestString = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
await Task.Delay(250);
}
}
}
}
Even though I see with debugger that I'm passing through the TestString setter, the MainWindow is not updated.
I'm quite sure I'm missing something trivial in setting DataContext of UC in MainWindow, but I've not been able to find what after several hours of browsing and thinking.
Any help appreciated.
The expression
<local:TestUC DataContext="{StaticResource TestUC_VM}"/>
assigns the value of the TestUC_VM resource to the UserControl's DataContext. This is a different object than the _uc_VM member of the main view model, which you are later updating.
Turn the member into a public property
public TestUC_VM UcVm { get; } = new TestUC_VM();
and write
<local:TestUC DataContext="{Binding UcVm}"/>
Update the view model like this:
UcVm.TestString = ...

Usercontrol binding lost on value updated, that doesn't happen with standard textbox control

I have a problem with binding in usercontrol.
This is my usercontrol:
UserControl1.xaml
<UserControl x:Class="WpfApp1.UserControl1"
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-ompatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
x:Name="usercontrol"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<TextBox Text="{Binding HmiField, ElementName=usercontrol}"/>
</Grid>
</UserControl>
UserControl1.xaml.cs
namespace WpfApp1
{
public partial class UserControl1 : UserControl
{
public double HmiField
{
get { return (double)GetValue(HmiFieldProperty); }
set { SetValue(HmiFieldProperty, value); }
}
public static readonly DependencyProperty HmiFieldProperty =
DependencyProperty.Register("HmiField", typeof(double), typeof(UserControl1));
public UserControl1()
{
InitializeComponent();
}
}
}
And this is the main window:
MainWindow.xaml
<Window x:Class="WpfApp1.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:WpfApp1"
mc:Ignorable="d"
DataContext="{Binding Md, RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="450" Width="800">
<UniformGrid>
<Button Content="{Binding Prop1}" Click="Button_Click"/>
<Label Content="{Binding Prop1}"/>
<TextBox Text="{Binding Prop1}"/>
<local:UserControl1 HmiField="{Binding Prop1}"/>
</UniformGrid>
</Window>
MainWindow.xaml.cs
namespace WpfApp1
{
public class tMd: INotifyPropertyChanged
{
#region Interfaccia INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}
#endregion
private double prop1;
public double Prop1 { get
{
return prop1;
}
set
{
if (prop1 != value)
{
prop1 = value;
NotifyPropertyChanged("Prop1");
}
}
}
}
public partial class MainWindow : Window
{
public tMd Md
{
get { return (tMd)GetValue(MdProperty); }
set { SetValue(MdProperty, value); }
}
public static readonly DependencyProperty MdProperty =
DependencyProperty.Register("Md", typeof(tMd), typeof(MainWindow), new PropertyMetadata(new tMd()));
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Md.Prop1 = 1234.5678;
}
}
}
I found some similar question:
How do I change TextBox.Text without losing the binding in WPF?
WPF: Binding is lost when bindings are updated
WPF Textbox TwoWay binding in datatemplate not updating the source even on LostFocus
But I can't completely understand what's happening: why a standard textbox work as expected and my usercontrol no?
Or better: is there a way to have my usercontrol works with the textbox's behaviour?
The Binding must be TwoWay, either set explicitly
<local:UserControl1 HmiField="{Binding Prop1, Mode=TwoWay}"/>
or implicitly by default:
public static readonly DependencyProperty HmiFieldProperty =
DependencyProperty.Register(
nameof(HmiField), typeof(double), typeof(UserControl1),
new FrameworkPropertyMetadata(
0d, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
A TextBox's Text property is registered like shown above, i.e. with the BindsTwoWayByDefault flag.
At the TextBox Binding in the UserControl's XAML you may also want to update the source property while the user is typing (instead of only on lost focus):
<TextBox Text="{Binding HmiField,
ElementName=usercontrol,
UpdateSourceTrigger=PropertyChanged}"/>
or without the otherwise useless generated usercontrol field:
<TextBox Text="{Binding HmiField,
RelativeSource={RelativeSource AncestorType=UserControl}
UpdateSourceTrigger=PropertyChanged}"/>
Your Prop1 notifies when it changes, but you haven't told you binding to trigger on that notification.
Try including UpdateSourceTrigger=PropertyChanged in you binding

Cannot get internal XAML binding to work against a Dependency Property

I have a user control "CtrlComments", this control has the following XAML (It's super basic).
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:wpftoolkit="http://schemas.microsoft.com/wpf/2008/toolkit"
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"
x:Name="ucRoot">
<Grid>
<StackPanel Orientation="Horizontal">
<TextBlock Text="ID: " />
<TextBlock Text="{Binding Path=Deployment.Id}" />
</StackPanel>
</Grid>
The code behind is as follows, it's the bare basics to get the control to function. The key is the DependencyObject typeof(DeploymentDto) which has an int property called Id that we are interested in showing on our window as per XAML binding above.
public partial class CtrlComments : UserControl, INotifyPropertyChanged
{
public static readonly DependencyProperty DeploymentProperty =
DependencyProperty.Register("Deployment", typeof(DeploymentDto),
typeof(CtrlComments), new PropertyMetadata(new DeploymentDto()));
public DeploymentDto Deployment
{
get
{
return (DeploymentDto)GetValue(DeploymentProperty);
}
set
{
SetValue(DeploymentProperty, value);
OnPropertyChanged(new PropertyChangedEventArgs("Deployment"));
}
}
public CtrlComments()
{
InitializeComponent();
this.DataContext = this;
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
}
}
Our problem is, despite the fact that the binding between the parent control and my user control via the dependency property is working (verified) and the OnPropertyChanged method firing, the TextBlock in my XAML isn't updating.
I have noticed that when the OnPropertyChanged method is run, the eventhandler is null meaning no one is notified that there was a property change.
I don't understand why this is the case though. If you could help explain where we are going wrong it would be enormously appreciated.
Thanks!
I have tried to replicate your problem and while doing so, I figured that the problem for me was in the following line in CtrlComments:
this.DataContext = this;
Dropping this line just made it work for me. Also note (as #Aron wrote in the comments) that the OnPropertyChanged of INotifyPropertyChanged shouldn't be called while in the setter of the DependencyProperty. At least for me it isn't necessary to implement INPC at all.
In the XAML file where you are using the UserControl you are most likely going to have another DataContext set (on a higher level, perhaps in the Window), and thus I guess it isn't inherited to the user control if already set in there (or overwritten). Below is my working code, but perhaps I misunderstood exactly what you're doing. If that is the case, please extend your question to include how you are using the UserControl, as that is a key to answering the question if this doesn't work :)
CtrlComments.xaml:
<UserControl x:Class="WpfApplication1.CtrlComments"
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>
<StackPanel Orientation="Horizontal">
<TextBlock Text="ID: "/>
<TextBlock Text="{Binding Path=Deployment.Id}"/>
</StackPanel>
</Grid>
</UserControl>
CtrlComments.xaml.cs:
namespace WpfApplication1
{
public partial class CtrlComments : UserControl
{
public static readonly DependencyProperty DeploymentProperty =
DependencyProperty.Register("Deployment", typeof(DeploymentDto), typeof(CtrlComments), new PropertyMetadata(new DeploymentDto { Id = 5 }));
public DeploymentDto Deployment
{
get { return (DeploymentDto)GetValue(DeploymentProperty); }
set
{
SetValue(DeploymentProperty, value);
}
}
public CtrlComments()
{
InitializeComponent();
}
}
}
MainWindow.xaml:
<Window x:Class="WpfApplication1.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:WpfApplication1"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<StackPanel>
<local:CtrlComments x:Name="testUC" Height="100" Deployment="{Binding Deployment}"/>
<Button Click="Button_Click" Height="50" Width="100"/>
</StackPanel>
</Window>
MainWindow.xaml.cs:
namespace WpfApplication1
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
}
private DeploymentDto deployment = new DeploymentDto { Id = 2 };
public DeploymentDto Deployment
{
get { return deployment; }
set { deployment = value; OnPropertyChanged("Deployment"); }
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Deployment = new DeploymentDto { Id = new Random().Next(100) };
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
}
DeploymentDto:
public class DeploymentDto
{
public int Id { get; set; }
}
It's quite ugly to bind MainWindow.DataContext to its code-behind, but since it's just used for example purposes I hope it's okay :)

Binding is not working on custom user control's dependency property

I've been working at this for awhile and seeming to not be able to find any good answers to my problem. I'm using a custom control that has custom dependency properties and in my main app I am binding to those propertys with my viewmodel that is seen through a viewmodel locator using mvvmlight. my question is why is the binding not updating nor seeing the correct datacontext?
Code:
User Control Xaml:
<UserControl x:Name="zKeyBoard"
x:Class="ZLibrary.ZKeyBoard"
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"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
d:DesignHeight="768" d:DesignWidth="1024">
<Grid>
<TextBox TextWrapping="Wrap" Text="{Binding zDisplayText}" />
<Label Content="{Binding zBoxToEdit}"/>
</Grid>
</UserControl>
Things I have Tried In The User Control Xaml Already:
<TextBox TextWrapping="Wrap" Text="{Binding zDisplayText, ElementName=zKeyBoard}" />
<Label Content="{Binding zBoxToEdit, ElementName=zKeyBoard}"/>
User Control C#:
using System.ComponentModel;
namespace ZLibrary
{
public partial class ZKeyBoard : UserControl, INotifyPropertyChanged
{
public ZKeyBoard()
{
InitializeComponent();
}
public string zBoxToEdit
{
get { return (string)GetValue(zBoxToEditProperty); }
set { SetValue(zBoxToEditProperty, value); }
}
public static readonly DependencyProperty zBoxToEditProperty =
DependencyProperty.Register("zBoxToEdit", typeof(string), typeof(ZKeyBoard), new UIPropertyMetadata(""));
public string zDisplayText
{
get { return (string)GetValue(zDisplayTextProperty); }
set { SetValue(zDisplayTextProperty, value); }
}
public static readonly DependencyProperty zDisplayTextProperty =
DependencyProperty.Register("zDisplayText", typeof(string), typeof(ZKeyBoard), new UIPropertyMetadata(""));
}
}
Things I have already tried in the user control C#:
public string zBoxToEdit
{
get;
set;
}
public string zDisplayText
{
get;
set;
}
Here is the Project Files Where the User Control Is Being Used:
APP.xaml:
<Application x:Class="WpfApplication1.App"
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:vm="clr-namespace:Sandstorm.ViewModel"
mc:Ignorable="d"
StartupUri="Main.xaml">
<Application.Resources>
<ResourceDictionary>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
</ResourceDictionary>
</Application.Resources>
</Application>
The ViewModel Locator:
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;
namespace Sandstorm.ViewModel
{
class ViewModelLocator
{
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<KeyBoardViewModel>(() =>
{
return new KeyBoardViewModel();
});
}
public KeyBoardViewModel KeyBoardViewModel
{
get { return ServiceLocator.Current.GetInstance<KeyBoardViewModel>(); }
}
public static void Cleanup()
{
// TODO Clear the ViewModels
}
}
}
The Xaml The User Control Is Being Used In:
<Page x:Name="keyboard_Frame"
x:Class="Sandstorm.keyBoard"
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:ZControls="clr-namespace:ZLibrary;assembly=ZLibrary"
DataContext="{Binding KeyBoardViewModel, Source={StaticResource Locator}}"
mc:Ignorable="d"
d:DesignHeight="768" d:DesignWidth="1024"
ShowsNavigationUI="False"
Title="KeyBoard">
<Grid>
<ZControls:ZKeyBoard zBoxToEdit="{Binding boxToEdit}" zDisplayText="{Binding keyboardEntry}" />
</Grid>
</Page>
When This Xaml is ran as is This Way It Throws an error in the console that says it can not find the binding property of either boxToEdit or keyboarEntry and it refrences the original ZKeyBoard Name as The place it can not be found... So I added this:
<ZControls:ZKeyBoard zBoxToEdit="{Binding boxToEdit, RelativeSource={RelativeSource Mode=TemplatedParent}}" zDisplayText="{Binding keyboardEntry, RelativeSource={RelativeSource Mode=TemplatedParent}}" />
Which caused the error to go away which I assume meant that it could find the viewmodel yet still nothing happened.
And Finally The View Model:
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System.ComponentModel;
namespace Sandstorm.ViewModel
{
class KeyBoardViewModel : ViewModelBase, INotifyPropertyChanged
{
private string _keyboardEntry;
private string _boxToEdit;
public KeyBoardViewModel()
{
_boxToEdit = "yay";
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
public string keyboardEntry
{
get { return this._keyboardEntry; }
set
{
if (this._keyboardEntry != value)
{
this._keyboardEntry = value;
this.OnPropertyChanged("keyboardEntry");
Console.Out.WriteLine(this._keyboardEntry);
}
}
}
public string boxToEdit
{
get { return this._boxToEdit; }
set
{
if (this._boxToEdit != value)
{
this._boxToEdit = value;
this.OnPropertyChanged("boxToEdit");
Console.Out.WriteLine(this._boxToEdit);
}
}
}
}
}
One Thing I noticed was that I can Not See The Console.out.writeline doing anything which to me means it is not setting at all. so lots of big questions as to why this is not working. Any Help on this would be amazing! it probably is something small and stupid but a second pair of eyes on this will probably notice it faster than me.
Simple answer:
Don't set the DataContext to self.
Problem resolved

Categories