Hello!
Is it possible to retrieve the instance of the DataContext of a UserControl within a WPF Application?
I have tried it with FrameworkElement.DataContextProperty, but FrameworkElement.GetProperty(FrameworkElement.DataContextProperty) just get's the FullName of the DataContext as a string.
I am working with VS2015, .NET Framework 4.5.2, MSTest (switching to MSTest V2 once no longer a prerelease).
Here's my example code of a MVVM WPF-Application:
Default App.xaml and App.xaml.cs, with StartupUri="MainWindow.xaml"
Command and ViewModel, see http://docs.telerik.com/data-access/quick-start-scenarios/wpf/quickstart-wpf-viewmodelbase-and-relaycommand#implementing-viewmodelbase-and-relaycommand.
MainWindow.xaml: (default Code-Behind)
<Window x:Class="WpfApplication.MainWindow" xmlns:local="clr-namespace:WpfApplication" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Grid> <local:MyUserControl AutomationProperties.AutomationId="UserControlId" /> </Grid></Window>
MyUserControl.xaml: (default Code-Behind)
<UserControl x:Class="WpfApplication.MyUserControl" xmlns:local="clr-namespace:WpfApplication" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <UserControl.DataContext> <local:MyDataContext /> </UserControl.DataContext> <Grid> <StackPanel> <Button AutomationProperties.AutomationId="ButtonId" Content="Click" Command="{Binding ClickCommand}" CommandParameter="{Binding ClickCommandParameter}" /> </StackPanel> </Grid></UserControl>
MyDataContext:
using System.Windows.Input;namespace WpfApplication{ public class MyDataContext : ViewModel { public ICommand ClickCommand { get; } public string ClickCommandParameter { get; } = "clicked"; public int Count { get; private set; } internal MyDataContext() { ClickCommand = new Command(OnClick); } private void OnClick(object obj) { Count++; } }}
Unit Test (MSTest):
using System.IO;using ArtOfTest.WebAii.Core;using ArtOfTest.WebAii.Silverlight;using ArtOfTest.WebAii.TestTemplates;using Microsoft.VisualStudio.TestTools.UnitTesting;using WpfApplication;namespace UnitTests{ [TestClass] public class MyUnitTests : BaseWpfTest { public TestContext TestContext { get; set; } [TestInitialize] public void MyTestInitialize() { Initialize(); string currentWorkingDirectory = Directory.GetCurrentDirectory(); string path = Path.Combine(currentWorkingDirectory, "..", "..", "..", "WpfApplication", "bin", "Debug", "WpfApplication.exe"); Manager.LaunchNewApplication(path); } [TestCleanup] public void MyTestCleanup() { CleanUp(); } [TestMethod] public void MyTestMethod() { FrameworkElement userControl = ActiveApplication.MainWindow.Find.ByAutomationId("UserControlId"); FrameworkElement button = userControl.Find.ByAutomationId("ButtonId"); Assert.AreEqual("Click", button.GetProperty(new AutomationProperty("Content", typeof(string)))); Assert.AreEqual("WpfApplication.Command", button.GetProperty(new AutomationProperty("Command", typeof(string)))); Assert.AreEqual("clicked", button.GetProperty(new AutomationProperty("CommandParameter", typeof(string)))); button.User.Click(); object dataContext = userControl.GetProperty(FrameworkElement.DataContextProperty); Assert.AreEqual("WpfApplication.MyDataContext", dataContext); //pass Assert.IsInstanceOfType(dataContext, typeof(MyDataContext), "''" + dataContext + "''"); //fail } }}
And are there any other ways to get and/or set a Property of a ViewModel alternatively?
From the code sample above, I would like to get the current value of MyDataContext.Count.
In my Unit Test, I want to Assert the incremented MyDataContext.Count property after each Button-Click.
Best wishes!
