2014-03-07 44 views
1

我有執行在其get功能的產量返回屬性:爲什麼屬性getter中的yield return會中斷WPF綁定?

數據:

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返回值,調用它並分配result.ToList( )屬性不會破壞任何東西。我仍然很好奇爲什麼發佈的代碼導致「TimePassed」綁定失敗(getter永遠不會被調用)。

另一個有趣的是,如果我使用Snoop來調查綁定,當我嘗試查看「已損壞」元素時,getter會被調用。

+2

請發佈此行爲的最低重複性示例。 –

+0

代碼已更新,足以讓我重現此問題。 – BradleyDotNET

+2

包含詳細解釋「破壞其他綁定」的含義。即你做什麼,期望什麼,發生了什麼。 – Grozz

回答

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; 
       } 
      } 
     } 
    } 
} 

我會仔細看看,並調整你的值來匹配,看看是否有幫助。如果沒有,那麼問題就在您發佈的代碼範圍之外。

+0

感謝這個,這個問題似乎非常不一致(與實際代碼中更多的綁定更一致),並且很可能是機器相關的。我認爲這是WPF源代碼中的一處衝突。再次感謝! – BradleyDotNET

+0

我想研究的是將其從IEnumerable更改爲實際列表或數組。如果綁定了多次,那麼每個綁定都會重置枚舉器並給出異常結果。 –

+0

它沒有多次綁定,但這是我最終必須做的。感謝您的幫助和建議! – BradleyDotNET

相關問題