我有一个在其get函数中执行yield return的属性:
数据:
public class TestSummary
{
[Description("Test1")]
public TestResult Test1 {get; set;}
[Description("Test2")]
public TestResult Test2 {get; set;}
}
public enum TestResult
{
Failed,
Passed
}
视图模型:
private TestSummary TestResults
{
get { return new TestSummary() { Test1=Failed, Test2=Passed }; }
}
public int TimePassed
{
get
{
return 2;
}
}
public IEnumerable<String> FailedTests
{
get
{
PropertyDescriptorCollection attributes = TypeDescriptor.GetProperties(TestResults);
foreach (PropertyInfo failedResult in typeof(TestSummary).GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.PropertyType == typeof(TestResult)).Where(t => (TestResult)t.GetValue(TestResults) == TestResult.Failed))
{
yield return ((DescriptionAttribute)attributes[failedResult.Name].Attributes[typeof(DescriptionAttribute)]).Description;
}
}
}
XAML:
<UserControl>
<UserControl.DataContext>
<local:ViewModel/>
</UserControl.DataContext>
<StackPanel>
<ItemsControl ItemsSource="{Binding FailedTests}"/>
<ProgressBar Value="{Binding TimePassed}"/>
</StackPanel>
</UserControl>
工作和编译就好(属性是IEnumerable类型)。您甚至可以绑定它,并且UI正确更新。但是,使用此代码会破坏其他控件上的其他(看似随机)绑定,甚至是其他用户控件内部的绑定。
我的问题是,为什么?这是完全有效的C#,如果有的话,它应该打破绑定的UI控件,而不是其他。
更新 更新的源代码更完整。当我使用上面的内容时,从未调用过“TimePassed”的getter,进度条的Value总是为0。
如果有帮助,在函数中使用相同的yield return,调用它并将result.ToList()赋值给属性不会破坏任何内容。我仍然很好奇为什么发布的代码导致“TimePassed”绑定失败(从未调用getter)。
同样有趣的是,如果我使用Snoop来调查绑定,当我尝试查看“已损坏”元素时,会调用getter来调用。
答案 0 :(得分:1)
一切正常。这是我的测试代码。
<Window x:Class="BindingTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:bindingTest="clr-namespace:BindingTest"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<bindingTest:ViewModel/>
</Window.DataContext>
<Grid>
<StackPanel>
<ItemsControl ItemsSource="{Binding FailedTests}"/>
<ProgressBar Value="{Binding TimePassed,Mode=OneWay}"/>
</StackPanel>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
namespace BindingTest
{
public class TestSummary
{
[Description("Test1")]
public TestResult Test1 { get; set; }
[Description("Test2")]
public TestResult Test2 { get; set; }
[Description("Test3")]
public TestResult Test3 { get; set; }
}
public enum TestResult
{
Failed,
Passed
}
public class ViewModel
{
private TestSummary TestResults
{
get { return new TestSummary()
{
Test1 = TestResult.Failed,
Test2 = TestResult.Passed,
Test3 = TestResult.Failed
}; }
}
public int TimePassed
{
get
{
return 2;
}
}
public IEnumerable<String> FailedTests
{
get
{
PropertyDescriptorCollection attributes = TypeDescriptor.GetProperties(TestResults);
foreach (PropertyInfo failedResult in typeof(TestSummary).GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => p.PropertyType == typeof(TestResult))
.Where(t => (TestResult)t.GetValue(TestResults,null) == TestResult.Failed))
{
yield return ((DescriptionAttribute)attributes[failedResult.Name].Attributes[typeof(DescriptionAttribute)]).Description;
}
}
}
}
}
我会仔细研究并调整您的值以匹配,看看是否有帮助。如果没有,则问题超出了您发布的代码的范围。