2012-02-25 32 views
10

Có cách nào để thêm một SortedList hoặc một từ điển vào một ResourceDictionary và sử dụng (và liên kết!) Nó với một điều khiển thông qua XAML?Thêm SortedList hoặc Dictionary <int, string> vào ResourceDictionary

Tôi đã thử điều này, nhưng tôi không thể tìm ra cách để làm điều đó:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:sys="clr-namespace:System;assembly=mscorlib" 
    xmlns:coll="clr-namespace:System.Collections.Generic;assembly=mscorlib"> 

    <x:Array x:Key="test" 
      Type="sys:Object"> 
     <coll:KeyValuePair>***</coll:KeyValuePair> 
    </x:Array> 
+0

'x: Array' sẽ là tốt nếu bạn thêm các giá trị * * theo thứ tự, bạn sẽ chỉ cần thêm người đầu tiên' 'và nó sẽ nhận được chỉ số' 0' và như vậy, các ràng buộc sau đó có thể nhắm mục tiêu chỉ mục bằng cách sử dụng '[0]'. –

+0

@SeToY, vui lòng đặt câu hỏi là đã trả lời. – Shimmy

+0

@Shimmy Đó là giữa đêm ở đây và tôi đã đi ngủ ;-) – SeToY

Trả lời

16

SortedList là dễ dàng như nó không phải là chung chung.

Nếu một lớp thực hiện IDictionary bạn có thể thêm giá trị bằng cách xác định chúng bằng các nút con bằng cách sử dụng x:Key để đặt khóa mà chúng sẽ được thêm vào từ điển.

xmlns:col="clr-namespace:System.Collections;assembly=mscorlib" 
<col:SortedList x:Key="list"> 
    <sys:String x:Key="0">Lorem</sys:String> 
    <sys:String x:Key="1">Ipsum</sys:String> 
    <sys:String x:Key="2">Dolor</sys:String> 
    <sys:String x:Key="3">Sit</sys:String> 
</col:SortedList> 
<!-- Usage: --> 
<ContentControl Content="{Binding [0], Source={StaticResource list}}" /> 

Các phím mục là chuỗi đây, để có được ints thực tế mà bạn có thể sử dụng một phần mở rộng đánh dấu tùy chỉnh mà phân tích các chuỗi int, hoặc bằng cách định nghĩa các phím như tài nguyên đầu tiên :

<sys:Int32 x:Key="key1">0</sys:Int32> 
<sys:Int32 x:Key="key2">1</sys:Int32> 
<sys:Int32 x:Key="key3">2</sys:Int32> 
<sys:Int32 x:Key="key4">3</sys:Int32> 

<col:SortedList x:Key="list"> 
    <sys:String x:Key="{StaticResource key1}">Lorem</sys:String> 
    <sys:String x:Key="{StaticResource key2}">Ipsum</sys:String> 
    <sys:String x:Key="{StaticResource key3}">Dolor</sys:String> 
    <sys:String x:Key="{StaticResource key4}">Sit</sys:String> 
</col:SortedList> 

Ràng buộc sau đó trở nên phức tạp hơn vì giá trị chỉ mục cần được đúc thành int một cách rõ ràng nếu không nó sẽ được hiểu là chuỗi.

<ContentControl Content="{Binding Path=[(sys:Int32)0], 
            Source={StaticResource list}}"/> 

Bạn không thể bỏ quaPath= vì một implementation detail.


Từ điển không dễ dàng vì chúng chung chung và hiện tại không có cách xây dựng đơn giản để tạo đối tượng chung trong XAML. Tuy nhiên, bằng cách sử dụng các phần mở rộng đánh dấu, bạn có thể tạo các đối tượng chung thông qua sự phản chiếu.

Triển khai IDictionary trên tiện ích mở rộng như vậy cũng cho phép bạn điền vào trường hợp mới được tạo. Đây là một rất sơ sài dụ:

public class DictionaryFactoryExtension : MarkupExtension, IDictionary 
{ 
    public Type KeyType { get; set; } 
    public Type ValueType { get; set; } 

    private IDictionary _dictionary; 
    private IDictionary Dictionary 
    { 
     get 
     { 
      if (_dictionary == null) 
      { 
       var type = typeof(Dictionary<,>); 
       var dictType = type.MakeGenericType(KeyType, ValueType); 
       _dictionary = (IDictionary)Activator.CreateInstance(dictType); 
      } 
      return _dictionary; 
     } 
    } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     return Dictionary; 
    } 

    public void Add(object key, object value) 
    { 
     if (!KeyType.IsAssignableFrom(key.GetType())) 
      key = TypeDescriptor.GetConverter(KeyType).ConvertFrom(key); 
     Dictionary.Add(key, value); 
    } 

    #region Other Interface Members 
    public void Clear() 
    { 
     throw new NotSupportedException(); 
    } 
    public bool Contains(object key) 
    { 
     throw new NotSupportedException(); 
    } 
    // <Many more members that do not matter one bit...> 
    #endregion 
} 
<me:DictionaryFactory x:Key="dict" KeyType="sys:Int32" ValueType="sys:String"> 
    <sys:String x:Key="0">Lorem</sys:String> 
    <sys:String x:Key="1">Ipsum</sys:String> 
    <sys:String x:Key="2">Dolor</sys:String> 
    <sys:String x:Key="3">Sit</sys:String> 
</me:DictionaryFactory> 

Như đi qua trong một trường hợp gõ như chính là một chút của một nỗi đau tôi đã chọn để làm việc chuyển đổi trong IDictionary.Add trước khi giá trị được bổ sung vào thay vào đó từ điển nội bộ (điều này có thể gây ra vấn đề với một số loại nhất định).

Vì chính từ điển được nhập ràng buộc nên không phải cần có dàn diễn viên.

<ContentControl Content="{Binding [0], Source={StaticResource dict}}" /> 
+0

Cảm ơn bạn đã trả lời tuyệt vời này, điều này đã giúp tôi rất nhiều :) – SeToY

+0

@SeToY: Bạn được chào đón, tôi nghĩ đó là một câu hỏi thú vị. –

+0

@ H.B. btw: congrats trên 40k –

Các vấn đề liên quan