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

7 posts, 0 answers
  1. Wetzorke
    Wetzorke avatar
    25 posts
    Member since:
    Aug 2012

    Posted 19 Dec 2016 Link to this post

    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!

  2. Elena Tsvetkova
    Admin
    Elena Tsvetkova avatar
    938 posts

    Posted 22 Dec 2016 Link to this post

    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
     
  3. Wetzorke
    Wetzorke avatar
    25 posts
    Member since:
    Aug 2012

    Posted 23 Dec 2016 in reply to Elena Tsvetkova Link to this post

    Hello Elena,

    thanks for your response.

    I have attached the project.

    Best wishes!
  4. Elena Tsvetkova
    Admin
    Elena Tsvetkova avatar
    938 posts

    Posted 28 Dec 2016 Link to this post

    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
     
  5. Elena Tsvetkova
    Admin
    Elena Tsvetkova avatar
    938 posts

    Posted 29 Dec 2016 Link to this post

    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
     
  6. Wetzorke
    Wetzorke avatar
    25 posts
    Member since:
    Aug 2012

    Posted 04 Jan 2017 in reply to Elena Tsvetkova Link to this post

    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!

  7. Elena Tsvetkova
    Admin
    Elena Tsvetkova avatar
    938 posts

    Posted 09 Jan 2017 Link to this post

    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
     
Back to Top