2009-07-23 19 views
6
<Window x:Class="WpfApplication1.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WpfApplication1" 
    Title="Window1"> 
    <Grid> 
     <local:ElementType x:Name="FirstElementName"> 
      <local:ElementType x:Name="SecondElementName" Grid.Column="1" Grid.Row="1" /> 
     </local:ElementType> 
    </Grid> 
</Window> 

Và đây là trong các tập tin khác ...Làm cách nào để có thể lồng các yếu tố XAML tùy chỉnh?

<Grid x:Name="InternalElementName" x:Class="WpfApplication1.ElementType" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WpfApplication1"> 
</Grid> 

Và ...

public partial class ElementType : System.Windows.Controls.Grid { } 

Tất cả mọi thứ hoạt động tốt, ngoại trừ yếu tố thứ hai.
Tôi gặp lỗi:
Không thể đặt giá trị thuộc tính Tên 'SecondElementName' trên phần tử 'ElementType'. 'ElementType' nằm trong phạm vi phần tử 'ElementType', đã có tên được đăng ký khi được xác định trong phạm vi khác.

Lưới tùy chỉnh được xác định chính xác. Mã sẽ biên dịch và chạy nếu tôi đưa ra tài sản ---

x:Name="SecondElementName" 

--- trong Window1.XAML

gì đang gây ra lỗi này? Làm thế nào để tôi có được nó? Tôi cần phải làm tổ một trong những lưới tùy chỉnh bên trong một trong những khác, và tôi cần tên trên cả hai người trong số họ vì vậy tôi có thể ràng buộc họ để tách dữ liệu.

Xin cảm ơn trước.

Trả lời

5

Để biết phải làm gì với các đối tượng đánh dấu lồng nhau, trình phân tích cú pháp XAML sẽ xem xét liệu lớp .NET có định nghĩa thuộc tính "nội dung" mặc định để sử dụng làm vùng chứa cho các trẻ đó hay không. Điều này được thực hiện với "ContentPropertyAttribute".

Trong trường hợp của bạn, vì tôi đoán bạn muốn đối tượng lồng nhau để đi vào bên trong lưới, và vì con cái của một mạng lưới đi trong "Trẻ em" bộ sưu tập thuộc tính, bạn chỉ cần làm như sau:

[ContentProperty("Children")] 
public partial class ElementType : Grid 
{ 
    // your code here... 
} 

Nếu bạn cần thực hiện một số logic khi thêm trẻ em vào kiểm soát của bạn (ví dụ: chỉ cho phép một số loại nhất định là con của điều khiển ElementType), bạn có thể kế thừa từ IAddChild và triển khai phương thức AddChild và AddText.

Đối với vấn đề đặt tên, có vẻ như chỉ có các điều khiển vô hình mới có thể đặt tên cho trẻ em trong phạm vi được lập trình. Vì vậy, về cơ bản, bạn có thể đặt tên cho trẻ em bên trong ElementType.xaml, nhưng không đặt tên cho trẻ em trong đánh dấu khác nơi bạn khởi tạo ElementType. Tôi đoán đó là vì cách họ tối ưu hóa cây hợp lý hay gì đó. Một điều khiển vô nghĩa, mặt khác, là một điều khiển chỉ với mã. Vì vậy, nếu bạn biến lớp học của bạn thành một lớp con trống cũ của Lưới, nó hoạt động:

public class ElementType : Grid 
{ 
} 

Yay! Ít mã hơn!

+0

Điều này cũng thú vị, nhưng nó vẫn không cho phép tôi cung cấp cho các đối tượng ElementType cha mẹ và con các tên khác nhau. Có ai biết làm thế nào tôi có thể nhận được chúng được đặt tên riêng biệt từ mỗi khác? – Giffyguy

+0

Ồ vâng, xin lỗi ... Tôi sẽ hoàn thành câu trả lời ở trên. – Ludovic

1

Nếu bạn muốn một trong khác, bạn muốn đặt bên trong một trong những sở hữu nội dung đầu tiên:

<local:ElementType x:Name="FirstElementName"> 
    <local:ElementType.Content> 
     <local:ElementType x:Name="SecondElementName" Grid.Column="1" Grid.Row="1" /> 
    </local:ElementType.Content> 
</local:ElementType> 

Ngoài ra, tôi không chắc chắn những gì bạn đang cố gắng để hoàn thành ở đây , nhưng tôi sợ nó.

+0

Âm thanh như thế này là đúng hướng để được hướng đến. Về vấn đề cuối cùng của bạn: HA! Tôi cố tình bỏ qua bất cứ thứ gì có thể đưa ra những chi tiết cụ thể --- tin tôi đi, bạn không muốn biết. Về giải pháp của bạn, tôi nhận được một lỗi: "Thuộc tính gắn liền 'Nội dung' không được tìm thấy trong loại 'ElementType'" Tôi đã cố gắng "Grid.Content" ở vị trí của nó và tôi nhận được gần như cùng một lỗi. Còn ý tưởng nào nữa không? – Giffyguy

+0

Tôi có nghĩa là "Trẻ em", không phải là Nội dung. Hình như bạn có nó, mặc dù. –

0

Nếu bạn không muốn thay đổi UserControl, hãy sử dụng hành vi đính kèm. Vì vậy, bạn chỉ cần nó ở đó, nơi mà XAML-Compile đã thất bại! Chỉ có 1 hành vi cho mỗi UserControl mà làm cho rắc rối.

trong XAML:

<preview:PreviewControl> 
    <i:Interaction.Behaviors> 
     <behaviors:UserControlNameBehavior Name="ICanSetNames"/> 
    </i:Interaction.Behaviors> 
</preview:PreviewControl> 

trong C#:

public class UserControlNameBehavior : Behavior<UserControl> 
    { 
     public string Name { get; set; } 

     protected override void OnAttached() 
     { 
      this.AssociatedObject.Loaded += OnLoaded; 
      base.OnAttached(); 
     } 

     private void OnLoaded(object sender, RoutedEventArgs routedEventArgs) 
     { 
      this.AssociatedObject.Name = this.Name; 
     } 
    } 
+0

Lớp Hành vi là gì? I là gì? –

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