2012-04-03 32 views
6

Đối đăng nhập hành động sử dụng trong các hình thức WPF của tôi, tôi đã thêm một số xử lý sự kiện toàn cầuCó bất kỳ số nhận dạng duy nhất nào cho wpf UIElement không?

Tôi muốn đăng nhập chính xác điều khiển hỏa lực sự kiện này, là có một số định danh duy nhất cho một WPF UIElement như ClientId trong ASP.Net?

+1

Bạn đã thử thuộc tính [FrameworkElement.Name] (http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.name.aspx) chưa? – DmitryG

+0

Yea Dmitry, nhưng Tên có thể trống, tôi không muốn đặt Tên trên mọi điều khiển dành riêng cho mục đích khai thác –

+0

@ArsenMkrt, [PersistId] (http://msdn.microsoft.com/en-us/library/ thuộc tính system.windows.uielement.persistid.aspx) có vẻ là những gì bạn đang tìm kiếm. Than ôi, nó bây giờ đã lỗi thời và dường như không có sự thay thế. Có thể bạn có thể quay trở lại để tự tạo các số nhận dạng duy nhất, trong trường hợp đó, hãy xem [câu hỏi này] (http://stackoverflow.com/q/750947/464709). –

Trả lời

2

Dường như tôi đã tìm thấy câu trả lời cho câu hỏi của mình, câu trả lời là Không, bây giờ là cách để làm điều đó, Như đã lưu ý trong MSDN tại đây (http://msdn.microsoft.com/en-us/magazine/dd483216.aspx)

Lưu ý rằng định nghĩa điều khiển cửa sổ cấp cao nhất không chứa thuộc tính Tên . Điều này là quan trọng bởi vì, như chúng ta sẽ thấy ngay, khi bạn viết tự động hóa thử nghiệm, một cách dễ dàng để tham chiếu đến điều khiển bằng cách sử dụng thư viện MUIA là truy cập thuộc tính AutomationId, được tạo bởi trình biên dịch từ thuộc tính Name của control. Điều khiển không có thuộc tính Tên XAML sẽ không nhận được thuộc tính AutomationId. Ý tưởng này là một ví dụ cụ thể, cấp thấp của tầm quan trọng của việc xem xét các vấn đề thiết kế ứng dụng cho mọi thứ chẳng hạn như bảo mật, khả năng mở rộng và tự động hóa thử nghiệm.

0

Bạn chỉ đang xem thêm Name hoặc x:Name sao cho Window/UserControl/Page hiển thị điều khiển cho phần còn lại của lớp với tên được chỉ định.

<Window ...> 
    <Grid> 
     ... 

     <!-- These controls are named, so you can access them directly by name --> 
     <Button x:Name="btnMyNamedButton" ... /> 
     <Button Name="btnMyOtherNamedButton" ... /> 

     <!-- This control is not named, so you can not directly access it by name --> 
     <Button ... /> 
    <Grid> 
</Window> 

public partial class MyWindow : Window 
{ 
    public MyWindow() 
    { 
     InitializeComponent(); 

     //btnMyNamedButton can be accessed 
     //btnMyOtherNamedbutton can also be accessed 

     //The third button can be accessed, but not directly by name. 
    } 
} 

Ngoài ra, bạn luôn có thể sử dụng đối tượng FrameworkElement.Tag. Nó có nghĩa là để lưu trữ thông tin tùy ý, vì vậy bạn có thể sử dụng thông tin này làm số nhận dạng duy nhất nếu bạn muốn.

+0

cảm ơn bạn đã trả lời @my, nhưng Tên không phải là thứ tôi đang tìm kiếm, lúc đầu tôi không muốn đặt tên cho tất cả các điều khiển UI một cách tinh vi để ghi nhật ký và thứ hai là không thể. các mẫu ô ... –

8

Tại sao bạn không sử dụng Mã băm.

Bạn có thể so sánh các giá trị để chắc chắn rằng họ là cùng một đối tượng, và nó dễ dàng để có được chúng với .GetHashCode()


Sửa

Rõ ràng đây là khác nhau mỗi khi bạn chạy chương trình, vì vậy thực sự đây là một ý tưởng tồi tệ, trừ khi bạn muốn cập nhật nhật ký mỗi lần quá trình được ghi lại. Vẫn có thể mặc dù

tôi có nghĩa là bạn có thể cửa hàng một giá trị băm cho từng đối tượng tại thời điểm log được tạo ra, nhưng tôi không biết nếu tôi thích điều đó

+0

Tôi đã kiểm tra và sự cố là GetHashCode() chỉ dành cho phiên đó. Nếu bạn tắt ứng dụng và khởi động lại các thành phần giao diện người dùng, tất cả sẽ nhận được HashCodes mới. Nhưng vẫn +1. – Paparazzi

+0

@ExitMusic, GetHashCode sẽ được thay đổi ít nhất là sau khi ứng dụng khởi động lại, điều này sẽ làm cho nhật ký không sử dụng được ... Tôi muốn có số nhận dạng ổn định hơn –

+0

Hashes không phải là duy nhất. –

0

Tôi tin rằng, để đăng nhập hành động của người dùng, bạn có thể sử dụng UIAutomation tree và thuộc tính AutomationElement.AutomationId, bởi vì phương pháp này được hỗ trợ trong tất cả các điều khiển giao diện người dùng chuẩn theo mặc định. Nhiều điều khiển của bên thứ ba cũng hỗ trợ AutomationId cho các phần tử của chúng (ví dụ: ô lưới). Một AutomationId hữu ích cho việc tạo các kịch bản tự động hóa thử nghiệm.

+0

Hmmmm ... có vẻ như AutomationId nên được đặt quá, và nếu nó không được đặt, nó sẽ trả về Tên trống trong trường hợp của chúng tôi ... Tôi đoán không có cách nào để làm những gì tôi đang tìm kiếm ... –

1

Một cách bạn có thể làm điều này là với thuộc tính tùy chỉnh. Giống như rất ...

Các UIElement bạn muốn đăng nhập (UserControl ví dụ):

[UserInterfaceID(ID = "{F436E9B3-C2F6-4CF8-8C75-0A2A756F1C74}")] 
public partial class MyUserControl : UserControl 
{ 
    InitializeComponent(); 
    // or whatever... 
} 

Sau đó, bạn cần tùy chỉnh thuộc tính lớp

[System.AttributeUsage(AttributeTargets.Class)] 
public class UserInterfaceIDAttribute : Attribute 
{ 
    public Guid ID { get; set; } 
} 

Bây giờ trong mã của bạn, bạn có thể làm một cái gì đó như thế này:

MyUserControl control = new MyUserControl(); 
foreach(object att in control.GetCustomAttributes(typeof(UserInterfaceAttribute),false)) 
{ 
    UserInterfaceAttribute uiAtt = (UserInterfaceAttribute)att; 
    Guid theID = uiAtt.ID; 
} 

Vì bạn đang gắn thẻ điều khiển với thuộc tính trong mã, số nhận dạng duy nhất không bao giờ thay đổi bất kể bạn đã giết/khởi chạy ứng dụng bao nhiêu lần.

Tất nhiên đây là một ví dụ cơ bản cho thấy cách truy cập ID nhưng có thể bạn sẽ muốn sử dụng một số loại Lập trình hướng Aspect. Tôi làm chính xác loại điều này bằng cách sử dụng Castle Windsor Interceptor, nhưng điều đó nằm ngoài phạm vi của bài đăng này.

Lý tưởng nhất là bạn sẽ truy cập ID này khi có một số loại sự kiện bị sa thải.Sử dụng interceptor cho phép bạn thực hiện các cuộc gọi phương thức capture trước khi chúng được gọi trong đó bạn có thể tra cứu ID như được hiển thị ở trên và ghi lại hành động. Ngoài ra, bạn chỉ có thể sử dụng

this.GetCustomAttributes(...) 

trong một số phương pháp khi sự kiện được kích hoạt trên kiểm soát và nhúng mã Đăng nhập của bạn vào đó. Mô hình này không phải là tốt nhất bởi vì bạn đang rải rác các mối quan tâm cắt ngang trên tất cả làm cho một số loại phương pháp lập trình hướng Aspect tốt hơn ... nhưng một lần nữa tôi digress và nó nằm ngoài phạm vi của bài đăng này ... nhưng bạn nhận được ý kiến.

Hy vọng điều này sẽ hữu ích.

+0

Tại sao tôi cần một thuộc tính? Tôi có thể đặt tất cả các thuộc tính Tên của các phần tử giao diện người dùng của mình, tôi chỉ muốn tìm cách mà không cần thiết lập bất kỳ điều gì, bởi vì nó có thể trong winform –

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