2012-04-03 68 views
19

Tôi đang cố gắng để đạt được một sử dụng bất thường của một Adorner. Khi bạn di chuột qua RichTextBox, một Adorner (xem sơ đồ bên dưới) sẽ xuất hiện phía trên nó, cho phép bạn thêm một danh sách các chuỗi vào một ListBox chứa trong Adorner. Điều này được sử dụng để thêm "thẻ" (à la Flickr) vào đoạn văn chứa trong phần tử được tô điểm.WPF adorner với các điều khiển bên trong

adorner diagram

Thứ nhất: là này thậm chí có thể?

Hầu hết các ví dụ về Adorners cho thấy cách ghi đè phương pháp OnRender của Adorner để thực hiện những việc tầm thường như vẽ hình dạng. Tôi đã có thể sử dụng điều này để hiển thị một tập hợp các hình chữ nhật tạo đường viền màu xám của Adorner, cũng tự động thay đổi kích cỡ nếu chiều cao của RichTextBox tăng do thêm dòng văn bản trong khi Adorner được hiển thị.

protected override void OnRender(DrawingContext drawingContext) 
{ 
    SolidColorBrush grayBrush = new SolidColorBrush(); 
    grayBrush.Color = Color.FromRgb(153, 153, 153); 

    // left 
    drawingContext.DrawRectangle(grayBrush, null, new System.Windows.Rect(1, 1, 5, ActualHeight)); 
    // right 
    drawingContext.DrawRectangle(grayBrush, null, new System.Windows.Rect(ActualWidth - 6, 1, 5, ActualHeight)); 
    //bottom 
    drawingContext.DrawRectangle(grayBrush, null, new System.Windows.Rect(1, ActualHeight, ActualWidth - 2, 5)); 

    // for reasons unimportant to this example the top gray bar is rendered as part of the RichTextBox 

} 

Tuy nhiên, việc thêm điều khiển có vấn đề hơn một chút. Nói chung, tính năng quảng cáo của WPF yêu cầu thêm điều khiển con trong mã thay vì XAML. Sử dụng kỹ thuật được mô tả trong DrawingContext adorner - possible to draw stackpanel?, tôi đã học cách thêm điều khiển con (như một TextBox) vào một Adorner mà không có bất kỳ vấn đề nào trong trình khởi tạo của Adorner.

Sự cố, tuy nhiên, là vị trí của các kiểm soát đó trong Adorner.

Nếu tôi có thể tạo lưới bằng nền màu xám và định vị nó ở dưới cùng của Adorner, tôi nên làm tốt. Tôi sẽ giả định (hy vọng) rằng những thứ như tự động thay đổi kích thước của Adorner dựa trên kích thước thay đổi của lưới đó như là thẻ được thêm vào sau đó sẽ xảy ra tự động.

Nói tóm lại, giả định này là có thể, bất cứ ai có thể giới thiệu một cách tạo này thấp hơn gắn thẻ khu vực kiểm soát trong các adorner và định vị nó tương đối so với đáy của adorner (mà có thể có thể phải thay đổi kích thước như RichTextBox đổi kích thước nội dung)?

Trả lời

38

Huzah! Với sự giúp đỡ của Ghenadie Tanasiev, tôi đã có câu trả lời.

Không giống như hầu hết các điều khiển trong WPF, adorners không có bất kỳ cách nào khác ngoài cách gán các phần tử con (chẳng hạn như các điều khiển tôi muốn thêm). Không thêm bất kỳ thứ gì vào trang sức, bạn chỉ có thể ghi đè lên phương thức OnRender của mình và vẽ nội dung trong số DrawingContext được chuyển vào đó. Thành thật mà nói, điều này có thể phù hợp với 99% trường hợp sử dụng cho adorners (thứ như tạo pull handle xung quanh một đối tượng), nhưng tôi cần thêm một số điều khiển thích hợp vào Adorner của mình.

Bí quyết để làm điều này là tạo một VisualCollection và đặt adorner làm chủ sở hữu của nó bằng cách chuyển nó vào trình tạo cho bộ sưu tập.

Đây là tất cả được mô tả khá toàn diện trong this blog article. Rất tiếc, các tìm kiếm Google lặp lại của tôi không chuyển bài viết này cho đến khi tôi biết tìm kiếm VisualCollection, nhờ có hướng dẫn của Ghenadie.

Điều này không được đề cập trong bài viết, nhưng lưu ý rằng có thể kết hợp kỹ thuật VisualCollection cùng với bản vẽ trong phương pháp OnRender của adorner. Tôi đang sử dụng OnRender để đạt được các cạnh bên và trên được mô tả trong sơ đồ của tôi ở trên và sử dụng VisualCollection để đặt và tạo các điều khiển.

Edit: đây là mã nguồn từ các bài viết trên blog đề cập vì nó không còn có sẵn:

public class AdornerContentPresenter : Adorner 
{ 
    private VisualCollection _Visuals; 
    private ContentPresenter _ContentPresenter; 

    public AdornerContentPresenter(UIElement adornedElement) 
    : base(adornedElement) 
    { 
    _Visuals = new VisualCollection(this); 
    _ContentPresenter = new ContentPresenter(); 
    _Visuals.Add(_ContentPresenter); 
    } 

    public AdornerContentPresenter(UIElement adornedElement, Visual content) 
    : this(adornedElement) 
    { Content = content; } 

    protected override Size MeasureOverride(Size constraint) 
    { 
    _ContentPresenter.Measure(constraint); 
    return _ContentPresenter.DesiredSize; 
    } 

    protected override Size ArrangeOverride(Size finalSize) 
    { 
    _ContentPresenter.Arrange(new Rect(0, 0, 
     finalSize.Width, finalSize.Height)); 
    return _ContentPresenter.RenderSize; 
    } 

    protected override Visual GetVisualChild(int index) 
    { return _Visuals[index]; } 

    protected override int VisualChildrenCount 
    { get { return _Visuals.Count; } } 

    public object Content 
    { 
    get { return _ContentPresenter.Content; } 
    set { _ContentPresenter.Content = value; } 
    } 
} 
+1

xem thêm http://social.msdn.microsoft.com/Forums/en-US/ wpf/thread/81eca7d5-88d7-477a-8cdb-cfb9e8b75379/ –

+0

Không rõ ràng. – Basic

3

Bạn không cần phải để tay bị bẩn, hãy xem this CodeProject article mà tôi đã sử dụng trong quá khứ.

Tính năng này cho phép bạn xác định các đồ trang trí trong XAML, thực hiện các liên kết, v.v.

+0

Tôi đã thực sự fiddled xung quanh với phương pháp này trong một vài giờ cố gắng để tìm ra một cách để thực hiện định vị được mô tả ở trên, nhưng tôi không nghĩ rằng mã trong ví dụ CodeProject đủ mạnh để chứa những gì tôi muốn làm. Ví dụ, nó đang cắt bất kỳ adorner nào tôi tạo ra cho các ranh giới của phần tử trang trí (rất kỳ quặc vì chỉ số z-adorners luôn được cho là đứng đầu). Tôi đã thử nghiệm những thứ như ràng buộc chiều cao của một phần tử trong AdornedControl.AdornerContent đến ActualHeight của phần tử được trang trí và nó đã thất bại (âm thầm) để làm như vậy. –

+0

Có nó không cắt, tôi thấy rằng nó clip để bố trí không để các yếu tố trang trí. Đối với vấn đề của bạn tôi sẽ có một cái nhìn khác –

+0

Je vous remercie, Baboon. :) Tôi sẽ giữ nó vào chiều nay bản thân mình và sẽ báo cáo bất cứ điều gì tôi học. –

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