Forum Discussion

sergi's avatar
sergi
Contributor
6 years ago

Cast to a custom Class

I'm trying to cast a property of a visual object to its actual type but an exception is raised complaining about invalid cast.

I've put together a very simple app and I'm trying to cast the ViewModel of an ItemsControl to the actual type of the ViewModel.

 

I've tried two different approaches and each one gives a different exception.

 

 

public class ListViewModel
    {
        public ObservableCollection<ItemViewModel> ItemsList { get; }

        public ListViewModel()
        {
            this.ItemsList = new ObservableCollection<ItemViewModel>();
        }
    }

 

App.xaml

 

<Application x:Class="TestApp.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:TestApp"
             Startup="App_OnStartup">
    <Application.Resources>
         
    </Application.Resources>
</Application>

 

 

public class ItemViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private string name;
        private string description;

        public string Name
        {
            get => this.name;
            set
            {
                if (this.name != value && value != null)
                {
                    this.name = value;
                    this.OnPropertyChanged(nameof(Name));
                }
            }
        }

        public string Description
        {
            get => this.description;
            set
            {
                if (this.description != value && value != null)
                {
                    this.description = value;
                    this.OnPropertyChanged(nameof(Description));
                }
            }
        }

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

 

MainWindow.xaml

 

 

<Window x:Class="TestApp.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"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <ItemsControl ItemsSource="{Binding ItemsList}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Name}"></TextBlock>
                        <TextBlock Text="{Binding Description}"></TextBlock>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Window>

 

App.xaml.cs

 

 

public partial class App
    {
        private void App_OnStartup(object sender, StartupEventArgs e)
        {
            ListViewModel listViewModel = new ListViewModel();
            listViewModel.ItemsList.Add(new ItemViewModel{Description = "Description1", Name = "Name1"});
            listViewModel.ItemsList.Add(new ItemViewModel { Description = "Description2", Name = "Name2" });

            MainWindow mainWindow = new MainWindow {DataContext = listViewModel};
            mainWindow.ShowDialog();
        }
    }

 

Then I try the following:

 

Option1

 

[TestMethod]
        public void HelloWorldTest()
        {
            IControl itemsControl = Driver.Find<IProcess>(new ProcessPattern() { ProcessName = "TestApp" })
                .Find<IControl>(new WPFPattern() { ClrFullClassName = "TestApp.MainWindow" }, 2)
                .Find<IControl>(new WPFPattern() { ClrFullClassName = "System.Windows.Controls.ItemsControl" }, 2);

            ListViewModel dataContextValue = itemsControl.GetProperty<IObject>("DataContext").Cast<ListViewModel>();
        }

 

 

Exception

Result StackTrace:    
at SmartBear.TestLeft.Utils.ImplementationsProvider.CreateImplementationObject(Type intfType, Object[] parameters)
   at SmartBear.TestLeft.Utils.ImplementationsProvider.CreateImplementationObject[T](Object[] parameters)
   at SmartBear.TestLeft.TestObjects.ObjectWrapper.Cast[T]()
   at TestLeftProject.TestLeftTest.HelloWorldTest() in c:\Users\LabCore\source\repos\TestApp\TestLeftProject\TestLeftTest.cs:line 38
Result Message:    
Test method TestLeftProject.TestLeftTest.HelloWorldTest threw exception:
System.InvalidOperationException: Can't find wrapper type by interface.



 

Option2

[TestMethod]
        public void HelloWorldTest()
        {
            IControl itemsControl = Driver.Find<IProcess>(new ProcessPattern() { ProcessName = "TestApp" })
                .Find<IControl>(new WPFPattern() { ClrFullClassName = "TestApp.MainWindow" }, 2)
                .Find<IControl>(new WPFPattern() { ClrFullClassName = "System.Windows.Controls.ItemsControl" }, 2);

            ListViewModel dataContextValue = itemsControl.GetProperty<ListViewModel>("DataContext");
        }

 

Exception

Result StackTrace:    
at SmartBear.TestLeft.TestObjects.ObjectWrapper.ConvertValue(Object value, Type targetType)
   at SmartBear.TestLeft.TestObjects.ObjectWrapper.ConvertValue[T](Object value)
   at SmartBear.TestLeft.TestObjects.ObjectWrapper.GetProperty[T](String name, Object[] parameters)
   at TestLeftProject.TestLeftTest.HelloWorldTest() in c:\Users\LabCore\source\repos\TestApp\TestLeftProject\TestLeftTest.cs:line 38
Result Message:    
Test method TestLeftProject.TestLeftTest.HelloWorldTest threw exception:
System.InvalidCastException: Unable to cast SmartBear.TestLeft.DriverImpl+ObjectInfo to TestApp.ListViewModel.



Is it a limiation of TestLeft? Is there any workaround?Thank you!

 

No RepliesBe the first to reply