簡體   English   中英

使用TestStack.White設置`VirtualizingPanel.IsVirtualizing`

[英]Setting `VirtualizingPanel.IsVirtualizing` with TestStack.White

在測試虛擬面板時,我需要設置VirtualizingPanel.IsVirtualizing屬性,以便Teststack.White可以像與非虛擬面板一樣與它們進行交互。

當面板內容很多時,這對我有幫助。

我不想靜態設置VirtualizingPanel.IsVirtualizing因此不必將其交付給客戶。

要玩一個最小的示例,您將需要一個窗口。

<Window x:Class="DataGridTest.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"
        xmlns:local="clr-namespace:DataGridTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <DataGrid
        AutomationProperties.AutomationId="MyDataGRID"
        ItemsSource="{Binding MyItems}" 
        VirtualizingPanel.IsVirtualizing="True" >
        <!-->  
        "IsVirtualizing Defaults to True."
        "Setting this to False makes the test pass but is a poor choice for production code."
        "Somehow I need to be able to change this programatically during testing."
        </!-->
    </DataGrid>
</Window>

上面的窗口后面的代碼。

using System.Collections.Generic;
using System.Windows;

namespace DataGridTest
{
    public class Item
    {
        private string str;
        public Item(string str) { this.str = str; }
        public string Value { get { return str; } }
        public int Length { get { return str.Length; } }
        public int Hash { get { return str.GetHashCode(); } }
    }

    public partial class MainWindow : Window
    {
        List<Item> myitems;
        public List<Item> MyItems { get { return myitems; } }

        public MainWindow()
        {
            InitializeComponent();

            myitems = new List<Item>();
            for (int i = 0; i < 800; ++i)
            {
                myitems.Add(new Item($"Item {i}"));
            }

            DataContext = this;
        }
    }
}

最后是一個測試項目:

using NUnit.Framework;
using System.Diagnostics;
using TestStack.White;
using TestStack.White.UIItems;
using TestStack.White.UIItems.WindowItems;

namespace NunitTest
{
    [TestFixture]
    public class Class1
    {
        private Application app;
        private Window window;

        [OneTimeSetUp]
        public void OneTimeSetUp()
        {
            ProcessStartInfo info = new ProcessStartInfo( $"{TestContext.CurrentContext.WorkDirectory}/DataGridTest.exe");
            info.WorkingDirectory = TestContext.CurrentContext.WorkDirectory;
            app = Application.Launch(info);
            window = app.GetWindow("MainWindow");
        }

        [OneTimeTearDown]
        public void OneTimeTearDown()
        {
            window.Close(); window = null;
            app.Close(); app = null;
        }

        [Test]
        public void test()
        {
            ListView list = window.Get<ListView>("MyDataGRID");
            SetIsVirtualizing(list, false);
            Assert.AreEqual(800, list.Rows.Count, "This fails for virtualized panels");
            SetIsVirtualizing(list, true);
        }

        private void SetIsVirtualizing(ListView list, bool value)
        {
            //insert magic - I tried a couple of things but I just can not set this dependency property
        }
    }
}

請幫助理解在測試過程中如何設置VirtualizingPanel.IsVirtualizing

通過添加折疊的文本框與datacontext進行交互,我取得了一些成功。 盡管我對該解決方案感到非常不滿意,但它確實通過了測試。

這是對我所做的代碼的修改:

窗口

<StackPanel>
    <TextBox 
    AutomationProperties.AutomationId="MyItems_IsVirtualizing_Injector"
    Text="{Binding MyItems_IsVirtualizing_Injector}" Visibility="Collapsed"/>
    <DataGrid
    AutomationProperties.AutomationId="MyDataGRID"
    ItemsSource="{Binding MyItems}" 
    VirtualizingPanel.IsVirtualizing ="{Binding MyItems_IsVirtualizing}"
        >
        <!-->  
    "IsVirtualizing Defaults to True."
    "Setting this to False makes the test pass but is a poor choice for production code."
    "Somehow I need to be able to change this programatically during testing."
    </!-->
    </DataGrid>
</StackPanel>

背后的代碼

    string injector = true.ToString();
    public event PropertyChangedEventHandler PropertyChanged = delegate { };
    public string MyItems_IsVirtualizing_Injector
    {
        get { return injector; }
        set
        {
            injector = value;
            PropertyChanged(this, new PropertyChangedEventArgs("MyItems_IsVirtualizing_Injector"));
            PropertyChanged(this, new PropertyChangedEventArgs("MyItems_IsVirtualizing"));
        }
    }
    public bool MyItems_IsVirtualizing { get { return string.Equals(true.ToString(), MyItems_IsVirtualizing_Injector); } }

測試

    private void SetIsVirtualizing(ListView list, bool value)
    {
        var injector = window.Get<TextBox>("MyItems_IsVirtualizing_Injector");
        injector.Text = value.ToString();
    }

編輯:由於我的實際用例正在計算元素,因此我實際上已經確定了可以使用CountElements(list.AutomationElement)調用的另一個解決方案

    private static int CountElements(AutomationElement container)
    {
        var patterns = container.GetSupportedPatterns();
        var itemContainer = container.GetCurrentPattern(ItemContainerPattern.Pattern) as ItemContainerPattern;

        List<object> elements = new List<object>();
        var element = itemContainer.FindItemByProperty(null, null, null);
        while (element != null)
        {
            elements.Add(element);
            element = itemContainer.FindItemByProperty(element, null, null);
        }
        return elements.Count;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM