2012-07-11 23 views
31

Từ một điều khiển tùy chỉnh dựa trên TextBox, tôi tạo ra một tài sản mang tên Items, theo cách này:A 'ràng buộc' chỉ có thể được đặt trên một thuộc tính phụ thuộc của một DependencyObject

public class NewTextBox : TextBox 
{ 
    public ItemCollection Items { get; set; } 
} 

Khi sử dụng điều khiển tùy chỉnh trong XAML , Tôi không thể ràng buộc tài sản vì nó làm tăng ngoại lệ "A 'Binding" chỉ có thể được đặt trên DependencyProperty của DependencyObject. "

Làm cách nào để giải quyết ngoại lệ này?

+2

Có.Chỉ các thuộc tính phụ thuộc mới có thể hoạt động như các mục tiêu cho các ràng buộc. Nguồn có thể là thuộc tính phụ thuộc hoặc thuộc tính CLR triển khai INotifyPropertyChanged – Gishu

+0

Đây là bản sao chính xác của câu hỏi khác của bạn, nơi bạn chấp nhận câu trả lời và nói "nhưng tôi phải sửa đổi thuộc tính để bao gồm DependencyProperty". Giải pháp của bạn nên được bao gồm dưới dạng câu trả lời ở đó – arserbin3

+5

@AdamHouldsworth Có, câu hỏi này đã được đăng chỉ để đăng câu trả lời. Điều này thực sự được khuyến khích vì nó được xem như một hình thức chia sẻ kiến ​​thức, và thậm chí còn có một [CheckBox' mới trên biểu mẫu Ask Question] (http://meta.stackexchange.com/questions/132886/what-is- this-answer-your-own-question-jazz) sẽ cho phép bạn viết câu trả lời cùng lúc khi bạn viết câu hỏi của mình. – Rachel

Trả lời

20

Để giải quyết ngoại lệ này, bạn cần phải thay đổi thuộc tính Items và thêm DependencyProperty sẽ hoạt động như một "liên kết" trong XAML. Lớp sẽ là:

public class AutocompleteTextBox : TextBox 
{ 
    public ItemCollection Items 
    { 
     get { 
      return (ItemCollection)GetValue(ItemsProperty); } 
     set { 
      SetValue(ItemsProperty, value); } 
    } 

    public static readonly DependencyProperty ItemsProperty = 
     DependencyProperty.Register(
      "Items", 
      typeof(ItemCollection), 
      typeof(AutocompleteTextBox), 
      new PropertyMetadata(default(ItemCollection), OnItemsPropertyChanged)); 

    private static void OnItemsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     // AutocompleteTextBox source = d as AutocompleteTextBox; 
     // Do something... 
    } 
53

Là một mặt lưu ý, nó cũng đáng chú ý là bạn sẽ nhận được các lỗi này ràng buộc nếu bạn sao chép và dán giữa các đối tượng và quên thay đổi các typeof(Object) tuyên bố thứ hai.

Tôi không thể tìm ra một giờ tốt vì sao tôi nhận được lỗi này vì mọi thứ dường như được xác định và chính xác. Tôi đã chuyển các thuộc tính của mình thành một usercontrol như tôi muốn chuyển từ một tập hợp đơn lẻ sang một danh sách. Như vậy:

public static readonly DependencyProperty FoldersProperty = DependencyProperty.Register("Folders", typeof(OutlookFolders), typeof(MainWindow), new FrameworkPropertyMetadata(new OutlookFolders())); 

public OutlookFolders Folders 
{ 
    get { return GetValue(FoldersProperty) as OutlookFolders; } 
    set { SetValue(FoldersProperty, value); } 
} 

nên đã trở thành:

public static readonly DependencyProperty FoldersProperty = DependencyProperty.Register("Folders", typeof(OutlookFolders), typeof(SavedFolderControl), new FrameworkPropertyMetadata(new OutlookFolders())); 

public OutlookFolders Folders 
{ 
    get { return GetValue(FoldersProperty) as OutlookFolders; } 
    set { SetValue(FoldersProperty, value); } 
} 

Cho đến khi tôi đã làm thay đổi này tôi vẫn tiếp tục nhận được lỗi: A 'Binding' cannot be set on the property 'Folders' of type 'SavedFolderControl'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.

+3

Điều này. Tôi đã sao chép một UserControl bằng một số DependencyProperties và điều đó có nghĩa là '' typeof (____) '' -Value cũ vẫn tồn tại và hợp lệ. Tôi không nhận được bất kỳ lỗi nào cho đến khi chạy. Và sau đó XAML phân tích ngoại lệ "Một ràng buộc chỉ có thể được thiết lập ..." và như vậy. Cảm ơn! – ecth

+0

Nó có thể tồn tại nhưng chấm các loại được đề xuất thực sự phù hợp. – netniV

+0

Không, đó là vấn đề. Tôi có nghĩa là lớp tồn tại và có giá trị. Vì vậy, bạn sẽ không nhận được bất kỳ lỗi nào trong VS. Cho đến khi bạn biên dịch và chạy. Nhưng sau đó bạn không biết nơi mà lỗi đến từ! Đó là màn sương mù của tôi sau khi sao chép .. – ecth

3

Một nguyên nhân tiềm năng của việc này là khi bạn cung cấp một loại xấu cho giá trị mặc định trong siêu dữ liệu.
Ví dụ:

new PropertyMetadata(default(ItemCollection), OnItemsPropertyChanged) 

sẽ ném lỗi này nếu bạn đã viết thay vì:

new PropertyMetadata(false, OnItemsPropertyChanged) 

này cũng có thể xảy ra nếu bạn đang sao chép và dán từ một mã nguồn.

16

Đây là một lưu ý khác: Đảm bảo rằng chuỗi trong đối số đầu tiên của DependencyProperty.Register() khớp với tên của thuộc tính liên quan.

public static readonly DependencyProperty ItemsProperty = 
    DependencyProperty.Register(
     "TheItems", // This is wrong 
     typeof(ItemCollection), 
     typeof(AutocompleteTextBox), 
     new PropertyMetadata(default(ItemCollection), OnItemsPropertyChanged)); 

Tôi gặp sự cố này khi đổi tên thuộc tính của mình mà không thay đổi chuỗi.

+4

Đảm bảo tên là "Mục", không phải "ItemsProperty" –

+7

Bạn có thể sử dụng tên (Mục) trong các phiên bản .NET gần đây để tránh sự cố này. – Herman

0

tôi đã được thông báo (runtime + designtime):

An unhandled exception of type 'System.Windows.Markup.XamlParseException' occurred in PresentationFramework.dll

Additional information: A 'Binding' cannot be set on the 'Property' property of type 'Trigger'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.

Nơi tôi đã đủ thông minh để xác định một Trigger trên một tài sản VM ..

// incorrect.. canont have Trigger for VM property 
<Trigger Property="{Binding IsExpanded}" Value="True"> 
    <Setter Property="Visibility" Value="Visible"/> 
</Trigger> 

nào nên ofcourse là một DataTrigger (sử dụng Binding thay vì Thuộc tính)

<dataTrigger Binding="{Binding IsExpanded}" Value="True"> 
    <Setter Property="Visibility" Value="Visible"/> 
</Trigger> 

Kích hoạt thường dành cho Control (Nút, Hộp văn bản) , FrameworkElement vv) thuộc tính.

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