2008-11-06 32 views
29

Tôi khá mới đối với WPF và tôi đang gặp vấn đề với kế thừa từ điều khiển người dùng.Thừa kế từ UserControl trong WPF

Tôi đã tạo Điều khiển người dùng và giờ tôi cần kế thừa từ điều khiển đó và thêm một số chức năng khác.

Có ai làm điều này trước đây không? Mọi sự trợ giúp sẽ rất được trân trọng.

Cảm ơn bạn

+2

cho cách giải quyết WPF với kế thừa Visual xem: http://svetoslavsavov.blogspot.gr/2009/09/user-control-inheritance-in-wpf.html hoặc để xác định rõ ràng GUI trong tổ tiên xem http: // support.microsoft.com/kb/957231 –

Trả lời

14

AFAIK bạn không thể kế thừa xaml, bạn chỉ có thể kế thừa mã đằng sau.

Gần đây, chúng tôi đã gặp sự cố tương tự về dự án của chúng tôi. Cách chúng tôi kết thúc giải quyết vấn đề của chúng tôi là tạo ra một usercontrol và thêm nó vào usercontrol "con".

Nếu đó doesnt làm việc/giúp đỡ hãy xem này: http://geekswithblogs.net/lbugnion/archive/2007/03/02/107747.aspx1

26

Vâng .. bạn tạo kiểm soát cơ sở của bạn

public abstract class BaseUserControl : UserControl{...} 

sau đó trong file XAML:

<Controls:BaseUserControl x:Class="Termo.Win.Controls.ChildControl" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:Controls="clr-namespace:Namespace.Of.Your.BaseControl"> 

Và đó nên làm việc.

EDIT: Hmm .. ví dụ này hữu ích khi bạn có điều khiển cơ sở không có XAML và sau đó kế thừa từ nó. Cách khác xung quanh (từ một điều khiển cơ sở với Xaml) - Tôi không chắc chắn làm thế nào bạn có thể đi về nó.

EDIT2: Dường như từ this post + comments tôi lấy điều bạn muốn có thể không thực hiện được.

+1

Giải pháp này phù hợp với tôi. – GeekyMonkey

+2

Theo như tôi có thể nhớ, nhà thiết kế phàn nàn khi bạn cố gắng kế thừa một lớp trừu tượng trong XAML. Nếu không thì điều này sẽ hoạt động tốt. – Entrodus

+0

Điều này cũng làm việc cho tôi. Cảm ơn! –

4

tôi có thể có một chút của một giải pháp: Thành phần thay vì thừa kế - Tôi đã đưa ra điều khiển, có 'khe nội dung' chuyển nhượng từ bên ngoài thông qua databinding, nhìn vào SO thread của tôi.

Ví dụ về sử dụng:

<UserControl ... > 

    <!-- My wrapping XAML --> 
     <Common:DialogControl> 
       <Common:DialogControl.Heading> 
         <!-- Slot for a string --> 
       </Common:DialogControl.Heading> 
       <Common:DialogControl.Control> 
         <!-- Concrete dialog's content goes here --> 
       </Common:DialogControl.Control> 
       <Common:DialogControl.Buttons> 
         <!-- Concrete dialog's buttons go here --> 
       </Common:DialogControl.Buttons> 
     </Common:DialogControl> 
    <!-- /My wrapping XAML --> 

</UserControl> 

Cùng với một số mã xử lý trong codebehind nó sẽ là một thành phần cơ bản tốt đẹp cho cửa sổ hộp thoại.

2

Bạn có thể thực hiện việc này bằng cách sử dụng delegate.

Về cơ bản, bạn cần phải tạo một giao diện (YourInterface) kết thúc tốt chức năng bạn muốn, sau đó kiểm soát người dùng và lớp của bạn triển khai giao diện đó.

Tiếp theo, hãy đảm bảo điều khiển người dùng có tham chiếu đến đối tượng thuộc loại IYourInterface, để khi người dùng của bạn kiểm soát nỗ lực gọi phương thức Interface, nó gọi phương thức của lớp của bạn. Bởi vì cả điều khiển người dùng và lớp thực hiện cùng một giao diện, chúng có thể được xem như cùng một loại đối tượng - nghĩa là bạn có thể đặt cả hai thành một tập hợp các đối tượng thuộc loại IYourInterface. Điều này sẽ cung cấp cho bạn các hành vi mà bạn muốn.

Trong ASP.NET tôi sử dụng kỹ thuật này thường xuyên, bằng cách có các lớp học của tôi kế thừa từ abstract class tổ tiên. Tôi không hiểu tại sao WPF không hỗ trợ điều này. :(

1

Bạn không thể kế thừa mã XAML nó tự Tuy nhiên việc tạo ra một lớp trừu tượng của codebehind, sẽ cho phép bạn chỉnh sửa trong mã phía sau, từ một đối tượng lớp được thừa kế

XAML Mã số:.. {Window1.XAML }

<Window 
x:Class="WPFSamples.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Height="auto" Width="256" Title="WPF Sameples"> 
    <Grid> 
    <Button x:Name="Button1" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Click Me"/> 
    </Grid> 
</Window> 

CodeBehind: {} Window1.xaml.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 

namespace WPFSamples 
{ 
    /// <summary> 
    /// Interaction logic for Window1.xaml 
    /// </summary> 
    public abstract partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 
     } 
    } 
} 

nguồn gốc class: {} DisabledButtonWindow.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace WPFSamples 
{ 
    public sealed class DisabledButtonWindow : Window1 
    { 
     public DisabledButtonWindow() 
     { 
      Button1.IsEnabled = false; 
     } 
    } 
} 

mặc dù bạn không thể kế thừa từ nguồn wpf nó tự, bạn có thể sử dụng điều khiển "Window1" làm mẫu cho tất cả các điều khiển có nguồn gốc khác.

1

Tôi nghĩ rằng bạn có thể làm điều này nhưng bạn sẽ phải xác định lại bất kỳ chức năng nào và có thể một số nội dung khác mà bạn tham chiếu trong xaml trong lớp con.

IE nếu bạn có sự kiện nhấp nút mà bạn đăng ký trong lớp cơ sở xaml, bạn sẽ cần ghi đè nhấp chuột vào nút con trong lớp con và gọi sự kiện nhấp nút lớp cơ sở.

Không chắc chắn một trăm phần trăm chi tiết vì đó là mã đồng nghiệp của tôi mà tôi đang vẽ nhưng nghĩ rằng điều này sẽ bắt đầu cho bất kỳ ai muốn thực hiện điều này trong tương lai.

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