2011-03-16 27 views
8

Có cách nào tốt để ràng buộc một thuộc tính với một giá trị const trong codebehind không?Ràng buộc thành viên const trong mã phía sau từ xaml trong WPF

Khi tôi sử dụng ComboBox, tôi thường làm theo cách này trong XAML và mã sau:

XAML:

<ComboBox Name="cbBuz"> 
    <ComboBoxItem Content="foo" Uid="foo" IsSelected="true" /> 
    <ComboBoxItem Content="bar" Uid="bar" /> 
</ComboBox> 

codebehind:

ComboBoxItem item = cbBuz.GetSelectedItem(); 
switch (item.Uid) 
{ 
    case "foo": ... break; 
    case "bar": ... break; 
} 

Lý do tại sao tôi đã chọn cách này là như sau:

  • Cho l mục đích ocalization, chuỗi nội dung không nên được sử dụng để xác định mục nào được chọn trong khi lưu và tải một mục được chọn cuối cùng.
  • Để đơn giản, XAML và mã phía sau phải được kết nối với số nhận dạng nội bộ (Trong trường hợp này là Uid). Vì vậy, XAML và Code-behind có thể được duy trì riêng biệt.

Tuy nhiên, bảo dưỡng-khôn ngoan, nhận dạng nội bộ nên được quy định tại một nơi như thế này:

//IDs 
public const string ID_foo = "foo"; 
public const string ID_bar = "bar"; 

... 

// 
switch (item.Uid) 
{ 
    case ID_foo: ... break; 
    case ID_bar: ... break; 
} 

Vấn đề là dường như bất động sản không thể giá trị const, do đó không có cách nào để ràng buộc ID_foo và ID_bar thành Uid của ComboBoxItem như sau:

//If ID_foo and ID_bar are properties, this will work. 
<ComboBox Name="cbBuz"> 
    <ComboBoxItem Content="foo" Uid="{Binding ID_foo}" IsSelected="true" /> 
    <ComboBoxItem Content="bar" Uid="{Binding ID_bar}" /> 
</ComboBox> 

Vì vậy, tôi muốn biết cách giải quyết vấn đề này. Hoặc, có cách nào tốt hơn để triển khai nó hay không. Nó sẽ là tốt đẹp, quá.

nhất,

Trả lời

18

Bạn sẽ khấm khá hơn bằng cách sử dụng StaticExtension, như vậy:

Uid="{x:Static local:YourClass.ID_foo}" 

đâu địa phương là một bí danh xmlns cho C# namespace của lớp học của bạn. Bạn có thể tìm thêm thông tin here.

Vấn đề với việc sử dụng Binding là bạn đang bổ sung thêm rất nhiều chi phí cho thứ gì đó sẽ không bao giờ thay đổi. Việc ràng buộc sẽ cố gắng theo dõi tài sản của bạn. Ngoài ra, có known "leaks" bằng cách sử dụng một Ràng buộc với thuộc tính không phụ thuộc vào đối tượng không triển khai INotifyPropertyChanged.

+0

Cảm ơn rất nhiều! Đây chính là điều tôi muốn!Ngoài ra, thông tin liên quan đến rò rỉ và chi phí thực sự hữu ích. – Aki24x

2

Bạn cần phải thực hiện một tài sản mà trả hằng số (được định nghĩa trong một const), ví dụ:

private const string ID_Foo = "foo"; 
public string FooId 
{ 
    get { return ID_Foo; } 
} 

Một khi điều này là trong một tài sản, nó sẽ được sử dụng thông qua ràng buộc.

+0

Ồ, đúng vậy. Có cách nào để làm ngắn hơn không? Ý tôi là nếu nó là C++, chúng ta có thể sử dụng #define để tạo macro, nhưng chúng ta không thể. Tôi tự hỏi IValueConverter và Enum có thể làm cho điều này ngắn hơn khi thêm Uid mới để ComboBox, không phải về khối lượng của toàn bộ mã. – Aki24x

+1

@ Aki24x: Bạn có thể làm điều này thông qua một IValueConverter và chỉ định một giá trị trong XAML như là một hằng số (không thông qua ràng buộc), thay vào đó. Điều đó sẽ cho phép một IValueConverter duy nhất để làm một tra cứu bằng cách nào đó, nhưng bạn cần một cái gì đó cho nó để tìm kiếm, ví dụ: một tên trong từ điển, hoặc sử dụng một enum, hoặc ... –

+0

Tôi thấy. Cảm ơn, Reed. =) – Aki24x

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