2011-06-20 32 views
1

試圖做這樣的事情......初始化一個ICollection的內XAML

public class MiniObject 
{ 
    public bool Checked { get; set; } 
    public String Caption { get; set; } 

    public ICollection<MiniObject> Content { get; set;} 
} 


<Window.Resources> 
    <local:MiniObject x:Key="RootItem" Caption="Item0" Checked="True"> 
     <local:MiniObject.Content> 
      <local:MiniObject Caption="Item1" Checked="True"> 
      </local:MiniObject> 
      <local:MiniObject Caption="Item2" Checked="True"> 
      </local:MiniObject> 
     </local:MiniObject.Content> 
    </local:MiniObject> 
</Window.Resources> 

這當然行不通返回錯誤:

Object of type 'WorkflowTest.MiniObject' cannot be converted to type 'System.Collections.Generic.ICollection`1[WorkflowTest.MiniObject]'. 

有沒有一種辦法中做到這一點WPF?如果是的話,我需要在所有的改變我的物體的形狀或可我只是規定,只有WPF使用像一個專門的對象......

<Window.Resources> 
    <local:MiniObject x:Key="RootItem" Caption="Item0" Checked="True"> 
     <local:MiniObject.Content> 
      <local:MiniObjectCollection> 
       <local:MiniObject Caption="Item1" Checked="True"> 
       </local:MiniObject> 
       <local:MiniObject Caption="Item2" Checked="True"> 
       </local:MiniObject> 
      </local:MiniObjectCollection> 
     </local:MiniObject.Content> 
    </local:MiniObject> 
</Window.Resources> 
+0

替換 public ICollection 內容{get;設置;} 與 public列表內容{get;設置;} 工程,但我需要避免使用實際的實現。使用IList導致相同的錯誤。 – NtscCobalt

+1

如果你不使用實際的實現,你將如何填充數據集合? –

+0

@John Gardner 我選擇ICollection的原因是因爲MiniObject在ORM中使用,我更喜歡它只使用像IList或ICollection這樣的接口。我在這裏寫的代碼是用於設計時間數據和測試。我不想寫一個單獨的課程,只是爲了讓設計師感到高興。 – NtscCobalt

回答

1

您正在嘗試使用XAML的隱式集合語法。爲此,屬性(Content,在這種情況下)必須是實現ICollection的類型。注意:不是ICollection,而是實現ICollection的類型。

您不能僅僅使用接口,因爲XamlReader需要知道要創建的對象類型。如果你還沒有告訴它這種類型,它應該如何決定?通過搜索組件中可用的所有類型,找到實現ICollection<MiniObject>的類型,丟棄那些沒有無參數構造函數的類型,然後隨機選擇一個類型?

當您將Content定義爲List<MiniObject>時,XamlReader知道應該創建什麼類型的對象。由於這是一種實現ICollection的類型,因此可以使用隱式集合語法。因此,它只是創建對象並調用Add來添加子項,並且如果您在那裏插入的子項不是MiniObject,則會出現運行時錯誤。

您在Content屬性中說「我需要避免使用實際實施」。在這種情況下,您不能使用隱式收集語法。您需要在第二個示例中執行以下操作:明確定義一個實現ICollection<MiniObject>的類型,並在您的XAML中添加一個子元素以明確創建它。

+0

從[MSDN](http://msdn.microsoft.com/en-us/library/ms753379.aspx#Collection_Properties)中,爲了在XAML中聲明集合屬性,集合類型可以是'IList'之一, 'IDictionary'和'Array'或實現'IAddChild',但你的答案聽起來好像'ICollection'確定。 –

+0

好吧,我想我明白了,這是有道理的,它不知道什麼類型的ICollection實施。現在我只需要弄清楚如何去做我在第二個例子中解釋的內容。謝謝。 – NtscCobalt

1

由於只有你的代碼上面提到的,它會拋出空引用異常寫在XAML集合屬性由於從MSDN的事實:

The presence of that collection type is implicit whenever you specify a property 
in XAML that takes a collection type. 

所以,我建議初始化的集合XAML如下,如果你不想在類聲明中有集合實例。

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:system="clr-namespace:System.Collections;assembly=mscorlib" xmlns:local="clr-namespace:WpfApplication1" Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <local:MiniObject x:Key="RootItem" Caption="Item0" Checked="True"> 
      <local:MiniObject.Content> 
       <system:ArrayList> -------------------------------------1) 
        <local:MiniObject Caption="Item1" Checked="True"> 
        </local:MiniObject> 
        <local:MiniObject Caption="Item2" Checked="True"> 
        </local:MiniObject> 
       </system:ArrayList> 
      </local:MiniObject.Content> 
     </local:MiniObject> 
    </Window.Resources> 
    <Grid> 
     <ListBox ItemsSource="{Binding Source={StaticResource ResourceKey=RootItem}, Path=Content}" DisplayMemberPath="Caption"/> 
    </Grid> 
</Window> 


public class MiniObject 
{ 
    public bool Checked { get; set; } 
    public String Caption { get; set; } 

    public IList Content { get; set; } -----------------------------------------2) 
} 

在2),你可能知道有四種選擇(IList,IDictionary等)是XAML中的集合屬性。請參閱MSDN。上面,ICollection也可以,因爲這些項目被添加到ArrayList中。

在1),我們不能聲明一個泛型類型集合,但我知道它會盡快得到支持。

+0

非常有趣,很高興知道。我沒有投票作爲答案,主要是因爲它不適合我當前的實現,我需要一個已知類型的集合(我在樹視圖中訪問UI中的對象的一些變量)。我認爲這將是一個有用的功能,當泛型類型集合被實現時,但是現在我認爲它會比爲了設計時間/窗口。資源實例化而簡單地要求封裝更混亂。 – NtscCobalt

0

我也有類似的要求並實現你正在做@NtscCobalt以同樣的方式,得到了同樣的異常,

一個簡單的解決這個例外是,有些集合或者列表<>或OvservableCollection初始化內容屬性<>。

這對我有效。 此外,如果您使用IEnumerable而不是IList它會給建立錯誤。

private IList<MiniObject> _content = new List<MiniObject>(); 
public IList<MiniObject> Content 
{ 
    get 
    { 
     return _content; 
    } 
    set 
    { 
     _content=value; 
    } 
}