This is a migrated thread and some comments may be shown as answers.

How to get (a property of) DataContext of UserControl (WPF)

6 Answers 2930 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Wetzorke
Top achievements
Rank 1
Wetzorke asked on 19 Dec 2016, 03:26 PM

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:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             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!

6 Answers, 1 is accepted

Sort by
0
Elena
Telerik team
answered on 22 Dec 2016, 01:47 PM
Hello Christoph,

In general the Telerik Testing Framework is designed for functional testing. Though I would like to review your project to be able to provide a proper advice. Would it be possible to provide the VS project?  

Thanks! 

Regards,
Elena Tsvetkova
Telerik by Progress
 
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
 
0
Wetzorke
Top achievements
Rank 1
answered on 23 Dec 2016, 02:25 PM

Hello Elena,

thanks for your response.

I have attached the project.

Best wishes!
0
Elena
Telerik team
answered on 28 Dec 2016, 01:01 PM
Hi Christoph,

Thanks for providing the VS project. Please allow me some time to review it along with your query and I will get back to you. Thanks in advance for your understanding! 

Regards,
Elena Tsvetkova
Telerik by Progress
 
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
 
0
Elena
Telerik team
answered on 29 Dec 2016, 02:46 PM
Hi Christoph,

I managed to review the provided project. The GetProperty method returns string so it is expected that the type assertion will fail. This is how Test Studio gets these properties for that sample application. 

Regards,
Elena Tsvetkova
Telerik by Progress
 
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
 
0
Wetzorke
Top achievements
Rank 1
answered on 04 Jan 2017, 04:50 PM

Hello Elena,

thanks for your response.

Is there any other way to retrieve the current DataContext-Instance of a Window or UserControl of the WPF Application under Test?

Or is there any way to get the actual instance of a System.Windows.Window or System.Windows.Controls.UserControl, rather than the ArtOfTest.WebAii.Silverlight.FrameworkElement?

Best wishes!

0
Elena
Telerik team
answered on 09 Jan 2017, 12:14 PM
Hi Christoph,

Thank you for getting back to me. This is how Telerik Testing Framework gets the DataContext of a Windows or UserControl in general. 

In relation to your other question I would like to note this is outside of the testing framework and probably there is a way to retrieve this information. However please note that this is out of the support scope. 

Regards,
Elena Tsvetkova
Telerik by Progress
 
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
 
Tags
General Discussions
Asked by
Wetzorke
Top achievements
Rank 1
Answers by
Elena
Telerik team
Wetzorke
Top achievements
Rank 1
Share this question
or