问题描述
我定义了以下组合框:
<ComboBox x:Name="cmbCurrency"
ItemsSource="{Binding IsoCurrenciesList}"
DisplayMemberPath="Description"
SelectedValuePath="LocaleID"
SelectedValue="{Binding CurrencyId, Mode=TwoWay">
</ComboBox>
其中 IsoCurrenciesList
是一个 IEnumerable
- 由我们定义并在视图模型中声明为的类型:
Where IsoCurrenciesList
is an IEnumerable<IsoCurrency>
- the type being defined by us and declared in the view model as:
private IEnumerable<IsoCurrency> isoCurrenciesList;
public IEnumerable<IsoCurrency> IsoCurrenciesList
{
get { return isoCurrenciesList; }
set
{
isoCurrenciesList = value;
RaisePropertyChangedEvent("IsoCurrenciesList");
}
}
我的单元测试创建了一个视图和视图模型的实例,并在本地列表中设置了一些虚拟货币数据:
My unit test creates an instance of the view and view model and sets up some dummy currency data in a local list:
[TestInitialize]
public void TestInit()
{
_target = new View();
_viewModel = new ViewModel();
var ukp = new IsoCurrency { Code = "GBP", Description = "Pound Sterling", LocaleID = 826 };
var usd = new IsoCurrency { Code = "USD", Description = "US Dollar", LocaleID = 840 };
var eur = new IsoCurrency { Code = "EUR", Description = "Euro", LocaleID = 978 };
_currencies = new List<IsoCurrency> { ukp, usd, eur };
GetUIElement<Grid>("LayoutRoot").DataContext = _viewModel;
}
private T GetUIElement<T>(string name) where T : UIElement
{
return (T)_target.FindName(name);
}
然后调用测试方法.这应该设置货币 ComboBox.Items
(通过 ItemsSource
属性)
Then the test method is called. This should set the currency ComboBox.Items
(via the ItemsSource
property)
[Asynchronous]
[TestMethod]
public void TestCurrencySelection()
{
_target.Loaded += (s, e) =>
{
// Set the currency list explicitly
_viewModel.IsoCurrenciesList = _currencies;
var currencyCombo = GetUIElement<ComboBox>("cmbCurrency");
// This assert fails as Items.Count == 0
CollectionAssert.AreEquivalent(currencyCombo.Items, _currencies, "Failed to data-bind currencies.");
EnqueueTestComplete();
};
TestPanel.Children.Add(_target);
}
我已遵循 Jeremy 上的准则Likeness 的博客,但我无法通过绑定测试.
I've followed the guidelines on Jeremy Likeness's blog but I can't get the bindings test to pass.
我尝试过测试其他属性的绑定 - 简单字符串、布尔值和整数,但在任一端所做的更改不会反映到另一端.
I've tried testing the bindings of other properties - simple strings, booleans and integers but the changes made at either end aren't reflected to the other.
我唯一能想到的是,在将视图添加到 TestPanel
以激活"绑定之后,我还需要执行另一个步骤,但我不知道它可以做什么
The only thing I can think of is that there is another step I need to do after adding the view to the TestPanel
to "activate" the bindings, but I've no idea what it could be.
更新
我应该指出代码在实际应用中运行良好.根据评论(尤其是来自 Adam Sills 的评论),问题似乎出在我尚未发布的代码中 - 即它与我们构建 XAML 的方式有关,或者在我们设置 DataContext
的方式.至少我可以将精力集中在(希望)正确的领域.
I should point out that the code works fine in the actual application. Based on the comments (particularly those from Adam Sills) it looks like the problem lies in the code I haven't posted - i.e. it's something in the way we've structured the XAML or there's a difference in the way we set the DataContext
. At least I can concentrate my efforts in (hopefully) the right area.
看起来控件在视图中的位置确实很重要.页面 XAML 是这样的:
It appears that the position of the control in the view does matter. The page XAML is something like this:
<Grid x:Name="LayoutRoot">
<VisualStateManager.VisualStateGroups>
...
</VisualStateManager.VisualStateGroups>
<toolkit:BusyIndicator x:Name="activityControl"
IsBusy="{Binding IsBusy}"
BusyContent="{Binding BusyContent}" >
<Grid>
... The page definition including sub grids, stack panels
and the combo box I'm testing along with other controls
<ops:SaveConfirmation Grid.Row="1" Margin="5"
x:Name="saveConfirmation"
SavedState="{Binding VendorSaved, Mode=TwoWay}" />
</Grid>
</toolkit:BusyIndicator/>
</Grid>
BusyIndicator
是 Silverlight Toolkit 中的一个,SaveConfirmation
是我们编写的控件.
The BusyIndicator
is the one from the Silverlight Toolkit and SaveConfirmation
is a control we've written.
如果我测试 BusyIndicator
上的 IsBusy
绑定是否按预期工作.但是,如果我在失败的 SaveConfirmation
上测试 SavedState
绑定 - 我在测试中将 VendorSaved
属性设置为 true 但是当我得到控制绑定值为false.
If I test the IsBusy
binding on the BusyIndicator
that works as expected. However, if I test the SavedState
binding on the SaveConfirmation
that fails - I set the VendorSaved
property to true in the test but when I get the control the bound value is false.
var busyIndicator = GetUIElement<BusyIndicator>("activityControl");
Assert.AreEqual(busyIndicator.IsBusy, _viewModel.IsBusy, "Failed to data-bind busy indicator.");
var saveConfirmation = GetUIElement<SaveConfirmation>("saveConfirmation");
Assert.AreEqual(saveConfirmation.SavedState, _viewModel.VendorSaved, "Failed to data-bind saved state");
所以第一个测试通过,但第二个失败.
So the first test passes, but the second fails.
我需要做些什么来确保设置树中所有元素的绑定?
推荐答案
您已经包含了 ComboBox 的 XAML,但没有包含页面的其余部分.在您的测试中,您有 GetUIElement("LayoutRoot").DataContext = _viewModel;
.在您所遵循的示例中,他定义了:
You've included the XAML for your ComboBox, but not the rest of your page. In your test you have GetUIElement<Grid>("LayoutRoot").DataContext = _viewModel;
. In the example you're following, he defines:
<Grid x:Uid="LayoutRoot" x:Name="LayoutRoot" Background="White"
DataContext="{Binding Source={StaticResource VMLocator},Path=Cascadia}">
然后他测试绑定的控件直接嵌套在该网格内.您的页面设置是否相同?
and then the controls on which he's testing the bindings are nested directly inside that grid. Is your page setup the same way?
这篇关于为什么我的 Silverlight XAML 绑定的单元测试失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!