2011-02-10 26 views
14

Tôi đã bắt đầu để làm cho bản thân mình một danh sách các "gotchas WPF": những điều mà lỗi tôi và rằng tôi phải viết ra để nhớ vì tôi rơi cho họ mỗi khi ....Gotcha tồi tệ nhất trong WPF là gì?

Bây giờ, tôi chắc chắn tất cả các bạn đều tình cờ gặp các tình huống tương tự tại một thời điểm và tôi muốn bạn chia sẻ kinh nghiệm của mình về chủ đề:

Gotcha luôn mang lại cho bạn những gì? cái bạn thấy khó chịu nhất?

(Tôi có một vài vấn đề mà dường như được mà không có lời giải thích, có thể đệ trình của bạn sẽ giải thích cho họ)

Dưới đây là một vài trong số tôi gotchas "personnal" (được trình bày một cách ngẫu nhiên):

  1. Để một MouseEvent được kích hoạt ngay cả khi nhấp chuột trên nền "trong suốt" của điều khiển (ví dụ như nhãn) và không chỉ trên nội dung (Văn bản trong trường hợp này), Nền của điều khiển phải được đặt thành "Bàn chải .Transparent "và không chỉ" null "(giá trị mặc định cho nhãn)

  2. Dữ liệu DataContext của WPF DataGridCell là RowView mà ô đó thuộc về, không phải là CellView

  3. Khi bên trong một ScrollViewer, thanh cuộn được quản lý bởi chính trình cuộn scrollviewer (tức là thiết lập các thuộc như ScrollBar.Value là không có hiệu lực thi hành)

  4. Key.F10 không được kích hoạt khi bạn bấm "F10", thay vào đó bạn có được Key.System và bạn phải đi tìm kiếm e.SystemKey để có được những Key.F10

... và bây giờ bạn đang ở trên.

+0

Đây không thực sự là câu hỏi và do đó không phù hợp với trang web câu hỏi và câu trả lời. Bạn đang yêu cầu một "Danh sách X" và không có ai trả lời đúng hơn tất cả những người khác. – ChrisF

+3

@ChrisF: Dưới hình thức một câu hỏi ... "Một số gotchas WPF là gì?" và sau đó đánh dấu nó là wiki cộng đồng. Chúng tôi có rất nhiều loại câu hỏi đó. –

+3

@emddudley - a) chỉ người kiểm duyệt mới có thể đặt câu hỏi CW ngay bây giờ và b) đó vẫn là câu hỏi "danh sách x" và c) các quy tắc đã được thắt chặt vì hầu hết (nếu không phải tất cả) trong số các câu hỏi đó được hỏi. – ChrisF

Trả lời

7

1) Được sử dụng mỗi nửa giờ khi tôi chuyển đổi từ WinForms: sử dụng TextBlock instead of Label khi đặt văn bản ngẫu nhiên trên giao diện người dùng (hoặc không sử dụng bất kỳ thẻ nào, nếu văn bản là tĩnh)!

2) DataTriggers/Triggers không thể được đưa vào Control.Triggers, nhưng phải đi vào Control.Styles/Kiểu/Style.Triggers

3) Loại tài sản phải thực hiện của IList, không IList<T>, nếu tài sản sẽ được XAML công nhận là tài sản thu thập.

4) Trường hợp ngoại lệ chụp liên kết.

5) Sử dụng bộ chuyển đổi đơn lẻ/lớp chuyển đổi tĩnh, vì vậy bạn không phải tạo bộ chuyển đổi mới mỗi lần sử dụng.

6) Một loại cho giá trị mặc định của thuộc tính phụ thuộc đã được xác định rõ ràng: 0u như uint, (float) 0 như float, 0.0 như đôi ...

7) It matters if the control's property definitions are before or after its content.

8) KHÔNG BAO GIỜ sử dụng PropertyMetadata để đặt giá trị mặc định của loại tham chiếu DependencyProperty. Tham chiếu đối tượng giống nhau sẽ được gán cho tất cả các cá thể của lớp sở hữu.

+0

không biết về 2 & 3, những cái đẹp ... – David

13
  1. Luôn xem cửa sổ đầu ra cho lỗi ràng buộc. Bỏ qua đầu ra cửa sổ là một công thức cho nước mắt.

  2. Sử dụng PresentationTraceOptions.TraceLevel = "Cao" trong ràng buộc để có được thông tin ràng buộc tiết khi gỡ lỗi liên kết lỗi.

  3. Tạo tài nguyên tĩnh, không thay đổi như bàn chải PresentationOptions: Freeze = "True" để lưu tài nguyên khi chạy.

  4. Sử dụng DataGrid WPF làm dữ liệu. Sửa đổi nó để hoạt động như Excel là một nỗi đau lớn trong mông.

  5. BindingList<T> không hoạt động tốt với CollectionViewSource. Thay vào đó, hãy hiển thị ObservableCollection<T> từ các chế độ xem của bạn.

  6. Internet cung cấp một nửa tá ý tưởng khác nhau để hiển thị văn bản CueBanner trong hộp văn bản WPF. Tất cả chúng đều bị hỏng.

+0

+1 cho cái đầu tiên (sẽ đặt +2 nếu tôi có thể :)). Tôi không biết cái thứ hai chút nào. rất thú vị, mặc dù điều này không thực sự là một bản ghi nhớ. + 1 cũng cho 4 ... (Tôi đang ở giữa làm việc đó: /) – David

+0

@ David: Vâng, tôi cũng thế. Đó là một bài tập liên tục chiến đấu với sự tập trung của DataGrid cho tiêu điểm bàn phím. –

+0

Cửa sổ đầu ra có thể là một phao cứu sinh lớn khi gặp vấn đề với các ràng buộc. –

1

tôi nhận được một khá tiện lợi một tuần trước:

Khi khuôn mẫu một RichTextBox, xử lý sự kiện bên trong mẫu sau một con đường kỳ lạ không có gì để làm cả với đường hầm cũng không sủi bọt

ví dụ: Trong trường hợp của một sự kiện được cho là đường hầm: sự kiện đầu tiên đường hầm qua ContentPresenter, sau đó nó đường hầm trở lại từ phía trên cùng của mẫu.

xem my question on the subject

2

ToolTips và ContextMenus không chia sẻ DataContext của chủ sở hữu của nó? Tôi nghĩ rằng tất cả mọi người được lúc đầu

0

yêu thích cá nhân của tôi là thế này:

public double MyVariable 
{ 
    get { return (double)GetValue(MyVariableProperty); } 
    set { SetValue(MyVariableProperty, value); } 
} 
public static readonly DependencyProperty MyVariableProperty = DependencyProperty.Register(
    "MyVariable", typeof(double), typeof(MyControl), new UIPropertyMetadata(0)); 

Hãy thử nó, một khi khách sạn này được khai báo nó sẽ sụp đổ. Tại sao? Bởi vì 0 không thể được gán cho một đôi khi sử dụng sự phản chiếu rõ ràng.

Không thực sự là một bản ghi nhớ nhưng một lời khuyên: Sử dụng Snoop hoặc một cái gì đó tương tự, nếu bạn không sử dụng nó, bạn phải điên ... Crazy tôi nói với ya!

1

Không có cách nào sạch để xử lý xác nhận trong WPF, tôi không phải là một fan hâm mộ của chuỗi ma thuật mà IDataErrorInfo cung cấp theo mặc định:

public string this[string columnName] 
    { 
     if (columnName == "FirstName") 
     { 
      if (string.IsNullOrEmpty(FirstName)) 
       result = "Please enter a First Name"; 
     } 
    } 

Tuy nhiên, tôi đã thử nhiều khuôn khổ như SimpleMVVM, FluentValidation và MVVMValidation và THEO FAR MVVM Validation là tốt nhất nhận được để làm công cụ như:

Validator.AddRule(() => RangeStart, 
      () => RangeEnd, 
      () => RuleResult.Assert(RangeEnd > RangeStart, "RangeEnd must be grater than RangeStart"); 
+0

Không có cách nào được tích hợp sạch sẽ - tôi sẽ không gọi đây là hình ảnh xác thực.Hãy nhớ rằng, toàn bộ XAML và sự hỗ trợ liên kết chỉ là một chuỗi các 'chuỗi ma thuật', các biểu thức phản chiếu và lưu trữ. Bạn hoàn toàn có thể trích xuất các tên thuộc tính từ các biểu thức http://stackoverflow.com/a/672212/286976 và trong .net 4.5, bạn có thể sử dụng '[CallerMemberName]' https://msdn.microsoft.com/en-us/library /system.runtime.compilerservices.callermembernameattribute%28v=vs.110%29.aspx – Gusdor

+0

'INotifyDataErrorInfo' cũng là một giao diện sạch hơn để thực hiện cho WPF. – Gusdor

0

Binding.StringFormat chỉ hoạt động nếu các loại tài sản mục tiêu là string.

2
  • Nếu được kích hoạt, Button.IsCancel gán false-Window.DialogResult nhưng Button.IsDefault không.
    Chúng rất giống nhau và đối với tôi nó có vẻ trực quan lúc đầu cả hai nên đóng hộp thoại. Tôi thường phá vỡ MVVM và sửa lỗi này trong code-behind

  • Button.IsCancel + Command = Dialog sẽ không chặt chẽ (Window.DialogResult trái unassigned) nhưng Command thực hiện
    Theo tôi được biết: Nếu IsCancel có ưu tiên cao hơn Command đó trở đi Esc nó sẽ gán 'false' cho DialogResultCommand sẽ không được gọi. Hoặc, nếu Command sẽ có mức ưu tiên cao hơn thì nó sẽ được gọi là đầu tiên và DialogResult sẽ được chỉ định. Tôi không hiểu nó bị bỏ qua như thế nào?

  • Ngoại lệ nuốt ràng buộc!
    Nó không chỉ đánh cắp thời gian trong khi gỡ lỗi nó cũng sai từ quan điểm OOP vì nếu ngoại lệ được ném nó có nghĩa là một cái gì đó đặc biệt đã xảy ra ở đâu đó trong hệ thống của chúng tôi (bất cứ điều gì từ cung cấp dữ liệu sai đến truy cập trái phép vào bộ nhớ thất bại) có thể được xử lý chỉ khi bạn biết phải làm gì. Bạn không thể chỉ catch(Exception){} bắt tất cả và sau đó bỏ qua. Nếu có ngoại lệ chưa biết trong chương trình nó sẽ thông báo cho người dùng, đăng nhập và đóng không giả vờ như mọi thứ đều ok ...

  • HeaderContent có thể chỉ có một điều khiển con và không có đệm
    Tất cả mọi thứ nên có đệm thậm chí điều khiển logic (container), phải không? Tôi nghĩ nó không nhất quán. Bạn nghĩ sao?

  • Nếu bạn đặt tập trung để ListBox qua FocusManager.FocusedElement bạn vẫn sẽ không thể chuyển đổi nội dung của nó với bàn phím vì tập trung được thiết lập để ListBox es khung không nội dung của nó. Tôi nghĩ rằng tôi không biết giao diện người dùng API nào khác sẽ hiển thị thứ gì đó giống như các nút điều khiển cho lập trình UI nên được đóng gói từ chúng tôi bởi vì ListBox trừu tượng đại diện cho một danh sách, nó chỉ là danh sách những thứ không phải là danh sách những thứ trong hộp. ok nó có hộp trong tên của nó nhưng vẫn ... Chúng tôi gần như có hai điều khiển khác nhau ở đây. MVVM not breaking fix

  • ListBox.IsSynchronizedWithCurrentItem theo mặc định là false vì vậy nếu bạn gán giá trị khác nhau hoặc null để ItesSource sau đó SelectedItem vẫn giữ giá trị cũ cho đến khi người dùng chọn một cái gì đó từ một danh sách mới. Nó có thể mess lên CanExecute ví dụ. Cần phải đặt nó mọi lúc bằng tay.

  • Không ràng buộc tiếp xúc trong PasswordBox kết quả trong sự lãng phí thời gian và hacks bẩn ... Nhưng nó vẫn có một chuỗi bất động sản PasswordBox.Password tiếp xúc do đó, thậm chí không cố gắng tranh cãi về an ninh vì Snoop ...

  • Nó không phải là một gotcha nhưng bố trí bảng là như vậy IE6 IMO. Thiết kế vùng chứa giúp tách nội dung khỏi bố cục của nó.
    Bởi vì mỗi lần tôi cần phải thay đổi điều gì đó ở những nơi tôi cần phải làm lộn xộn với Grid.RowGrid.Column. Có, chúng tôi có DockPanel, StackPanel và những người khác nhưng bạn không thể thực hiện một số căn chỉnh cột bên trong chúng. (Và DockPanel giống như hình ảnh xác thực hoàn toàn riêng biệt) Nếu UniformGrid có thể tùy chỉnh nhiều hơn, nó sẽ là lý tưởng tôi nghĩ. Bạn luôn luôn cần phải lựa chọn giữa Grid và Panels và thường nếu bạn đạt được một cái gì đó bạn mất cái gì khác.

+0

Bạn không phá vỡ MVVM bằng cách đóng cửa sổ của bạn ở phía sau mã. Nếu chế độ xem của bạn đã được thay thế bằng một trang HTML, bạn sẽ chuyển hướng thay vì đóng cửa sổ. Mã để đóng/chuyển hướng thuộc về chế độ xem chứ không phải cho mô hình. MVVM! = Không có mã sau – Maxence

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