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!