Các tính năng ẩn của WPF và XAML?


123

Đây là một số lượng lớn các tính năng ẩn được thảo luận cho nhiều ngôn ngữ. Bây giờ tôi tò mò về một số tính năng ẩn của XAML và WPF?

Một cái tôi đã tìm thấy là sự kiện nhấp vào tiêu đề của ListView

<ListView x:Name='lv' 
      Height="150" 
      GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler">

Thuộc tính GridViewColumnHeader.Click không được liệt kê.

Một số tính năng có liên quan cho đến nay:

Xem thêm:

  1. Các tính năng ẩn của C #
  2. Các tính năng ẩn của Python
  3. Các tính năng ẩn của ASP.NET
  4. Các tính năng ẩn của Perl
  5. Các tính năng ẩn của Java
  6. Các tính năng ẩn của VB.NET
  7. Các tính năng ẩn của PHP
  8. Các tính năng ẩn của Ruby
  9. Các tính năng ẩn của C
  10. Và như thế........

7
Có một cái nhìn ở đây msdn.microsoft.com/en-us/l Library / . Sự kiện nhấp được kế thừa từ NútBase. Những gì bạn đang mô tả là các Sự kiện đính kèm, một khái niệm khá mạnh mẽ trong WPF ( msdn.microsoft.com/en-us/l Library / bb613550.aspx ). Bằng cách này, bạn có thể thực hiện <Grid Button.Click> với 100 nút trên lưới và chỉ có 1 trình xử lý.
Sorskoot

1
Lúc đầu, tôi giống như "ồ, chúng ta lại đi", nhưng sau đó tôi đã học được điều gì đó trong các câu trả lời nên tôi lấy lại tất cả: o: o
Sam Harwell

1
nên là wiki cộng đồng
tsilb

2
@tsilb Tôi không nghĩ nó phải là wiki cộng đồng, hãy xem liên kết này meta.stackexchange.com/questions/392/ chủ
Cholashagudda Prashant

Câu trả lời:


87

Đa khung (kết hợp với StringFormat):

<TextBlock>
  <TextBlock.Text>
    <MultiBinding StringFormat="{}{0}, {1}">
      <Binding Path="LastName" />
      <Binding Path="FirstName" />
    </MultiBinding>
  </TextBlock.Text>
</TextBlock>

1
tuyệt vời :-) trừ khi bạn đang sử dụng silverlight 4 hoặc sớm hơn. ngón tay đan chéo cho v5
Simon_Weaver

5
Điều này thật tuyệt, nhưng tôi không muốn làm điều đó. Nếu tôi cần xây dựng một chuỗi, tôi sẽ phân loại theo logic và muốn kiểm tra đơn vị đầu ra. Những thứ như thế này đôi khi tốt hơn trong mô hình xem dưới dạng chuỗi.Format ().
Người giữ Iain

58

Ngoài ra còn có thủ thuật PresentationTraceSource.TraceLevel để gỡ lỗi những gì đang xảy ra với các ràng buộc trong bất kỳ kịch bản cụ thể nào. Tất cả bạn phải làm là tham chiếu không gian tên System.Diagnostics trong cụm WindowsBase

xmlns:sd="clr-namespace:System.Diagnostics;assembly=WindowsBase"

và sau đó thêm sau vào biểu thức ràng buộc:

<TextBlock Text="{Binding Message, sd:PresentationTraceSources.TraceLevel=High}"  />

Nhật ký sẽ như thế này:

System.Windows.Data Warning: 52 : Created BindingExpression (hash=5923895) for Binding (hash=7588182)
System.Windows.Data Warning: 54 :   Path: 'Message'
System.Windows.Data Warning: 56 : BindingExpression (hash=5923895): Default mode resolved to OneWay
System.Windows.Data Warning: 57 : BindingExpression (hash=5923895): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 58 : BindingExpression (hash=5923895): Attach to System.Windows.Controls.TextBlock.Text (hash=65248697)
System.Windows.Data Warning: 63 : BindingExpression (hash=5923895): Resolving source 

4
Trong VisualStudio 2010, bạn cần đặt mức cài đặt theo dõi thành cảnh báo! Xem stackoverflow.com/questions/2802662/ từ
WaltiD

44

3.5sp1 đã giới thiệu TargetNullValue cho các ràng buộc. Điều này sẽ đặt thuộc tính ràng buộc thành Null nếu giá trị được nhập và nếu thuộc tính của bạn là Null, nó sẽ hiển thị giá trị này.

<TextBox Text="{Binding Total, TargetNullValue=$0.00}" />

44

3.5sp1 đã giới thiệu StringFormat vào các biểu thức liên kết, ví dụ:

<TextBox Text="{Binding Date, StringFormat='{}{0:MM/dd/yyyy}'}" />

Tôi không thể nói thành lời tôi yêu thích tính năng đó đến mức nào. Tôi ghét có hàng tấn công cụ chuyển đổi giá trị nằm xung quanh.
Cướp

Vâng, dễ dàng là một trong những tính năng tiết kiệm thời gian nhất được thêm vào. Đặc biệt khi kết hợp với TargetNullValue rất nhiều vấn đề biến mất.
Bryan Anderson

6
Đặt các trích dẫn đơn xung quanh StringFormat sẽ xóa một số cảnh báo của trình biên dịch -Text={Binding Date, StringFormat='{}{0:MM/dd/yyyy}'}"
Ryan Versaw

Điều tốt để biết, tôi đã quen với việc bỏ qua chúng.
Bryan Anderson

1
Tôi đã cố gắng truyền đạt rằng bất kỳ chuỗi định dạng tùy ý sẽ hoạt động. Tôi tin rằng phiên bản quốc tế hóa sẽ là StringFormat = '{} {0: d}' trong trường hợp này.
Bryan Anderson

29

Đôi khi bạn nhận được chuỗi quá dài để hiển thị trên nhãn. Trong trường hợp này, chúng ta có thể sử dụng thuộc TextTrimmingtính của TextBlockđể hiển thị Ellipses

<TextBlock 
  Name="sampleTextBlock" 
  TextTrimming="WordEllipsis" 
  TextWrapping="NoWrap"/>

Liên kết MSDN


Hãy xem xét thêm một tooltip trong trường hợp như vậy: tranxcoder.wordpress.com/2008/10/12/...
surfen

27

Thêm hiệu ứng hàng không vào cửa sổ

  <Window.Resources>
    <ResourceDictionary Source="/PresentationFramework.Aero, Version=3.0.0.0, Culture=neutral, 
        PublicKeyToken=31bf3856ad364e35, ProcessorArchitecture=MSIL;component/themes/aero.normalcolor.xaml" />
</Window.Resources>

1
Đã thêm mã nhưng vẫn không thêm hiệu ứng Aero. Tui bỏ lỡ điều gì vậy?
Elmo

21

Generics trong XAML với x: TypeArgument

Nếu bạn muốn sử dụng một ObservableCollection trong XAML, bạn cần tạo một loại xuất phát từ ObservableCollection vì bạn không thể khai báo nó trong XAML. Với XAML 2009, bạn có thể sử dụng thuộc tính x: TypeArgument để xác định loại của một loại chung.

<!-- XAML 2006 -->
class EmployeeCollection : ObservableCollection<Employee>
{
}

<l:EmployeeCollection>
    <l:Employee FirstName="John" Name="Doe" />
    <l:Employee FirstName="Tim" Name="Smith" />
</lEmployeeCollection>

<!-- XAML 2009 -->
<ObservableCollection x:TypeArguments="Employee">
    <l:Employee FirstName="John" Name="Doe" />
    <l:Employee FirstName="Tim" Name="Smith" />
</ObservableCollection />

1
Thật không may, x: TypeArgument chỉ có sẵn trong các tệp xaml lỏng lẻo và không được biên dịch :(
kevindaub

Đúng, chỉ xaml lỏng lẻo :( Đối với phần lớn các nhà phát triển WPF XAML2009 là vô dụng.
Grigory

19

Hiển thị Tooltip trên một điều khiển bị vô hiệu hóa

Wpf cho phép hiển thị chú giải công cụ trên điều khiển, nếu nó ở trạng thái bị tắt.

Ví dụ

<Button Content="Disabled Button" ToolTipService.ShowOnDisabled="True" IsEnabled="False" ToolTip="This is a disabled button"/> 

19

Sử dụng Trình xây dựng không mặc định với x: Đối số

Trong XAML 2006, các đối tượng phải có một hàm tạo mặc định công khai để sử dụng chúng. Trong XAML 2009, bạn có thể truyền các đối số của hàm tạo bằng cách sử dụng cú pháp x: Đối số.

<!-- XAML 2006 -->
<DateTime>00:00:00.0000100</DateTime>

<!-- XAML 2009 -->
<DateTime>
    <x:Arguments>
        <x:Int64>100</x:Int64>
    </x:Arguments>
</DateTime>


18

Phần mở rộng đánh dấu và thuộc tính đính kèm là các tính năng yêu thích của tôi, chúng cho phép bạn mở rộng "từ vựng" XAML một cách rất thanh lịch.

Phần mở rộng đánh dấu

<!-- Binding to app settings -->
<CheckBox IsChecked="{my:SettingBinding MinimizeToTray}">Close to tray</CheckBox>

<!-- Fill ItemsControl with the values of an enum -->
<ComboBox ItemsSource="{my:EnumValues sys:DaysOfWeek}"/>

<!-- Localization -->
<TextBlock Text="{my:Localize HelloWorld.Text}"/>

<!-- Switch on the result of a binding -->
<TextBlock Text="{my:Switch Path=IsGood, ValueIfTrue=Good, ValueIfFalse=Bad}"/>

Tài sản đính kèm

<!-- Sort GridView automatically -->
<ListView ItemsSource="{Binding Persons}"
      IsSynchronizedWithCurrentItem="True"
      util:GridViewSort.AutoSort="True">
    <ListView.View>
        <GridView>
            <GridView.Columns>
                <GridViewColumn Header="Name"
                                DisplayMemberBinding="{Binding Name}"
                                util:GridViewSort.PropertyName="Name"/>
                <GridViewColumn Header="First name"
                                DisplayMemberBinding="{Binding FirstName}"
                                util:GridViewSort.PropertyName="FirstName"/>
                <GridViewColumn Header="Date of birth"
                                DisplayMemberBinding="{Binding DateOfBirth}"
                                util:GridViewSort.PropertyName="DateOfBirth"/>
            </GridView.Columns>
        </GridView>
    </ListView.View>
</ListView>


<!-- Vista Glass effect -->
<Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:my="clr-namespace:WpfApplication1"
        Title="Window1"
        my:WinUtil.EnableAeroGlass="True">

...

Nguồn cho GridViewSort (btw, nó sử dụng GridViewColumnHeader.Clicksự kiện được đề cập bởi Ortus)


Là nguồn WinUtil.EnableAeroGlasscó sẵn ở đâu đó?
Oskar

Có, nhưng nó đã thay đổi rất nhiều kể từ khi tôi đăng bài này ... Hiện tại có 2 thuộc tính, EnableBlur và GlassFrameMargins. Bạn có thể tìm thấy mã ở đây: projets.developpez.com/projects/dvp-net/reposeective/entry/trunk/ Kẻ
Thomas Levesque

15

Bạn có thể tham khảo các kiểu lồng nhau trong XAML bằng dấu cộng ( +). Ví dụ, nếu chúng ta có lớp này:

public class SomeClass
{
    public enum SomeEnum
    {
        SomeValue
    };
}

Chúng ta có thể tham khảo SomeValuetrong XAML bằng cú pháp sau:

{x:Static local:SomeClass+SomeEnum.SomeValue}

Cú pháp này không được ghi lại trên MSDN và nó không được hỗ trợ chính thức. Ai đó đã hỏi về nó trên các diễn đàn MSDN và dường như nó phá vỡ WPF Designer của VS2010. Nó đã được báo cáo trên Microsoft Connect.


14

Chia sẻ kích thước lưới ( đây là một ví dụ tốt). Câu chuyện dài bạn có thể có các cột lưới và các hàng chia sẻ kích thước, thậm chí trên các lưới khác nhau. Điều này sẽ là vô giá đối với tất cả những người đang sử dụng DataGrids mà không cần chỉnh sửa dữ liệu tại chỗ.


11

Ưu tiên ràng buộc . Cho phép bạn sử dụng các ràng buộc asyn theo thứ tự "lần đầu tiên đến trước":

<TextBlock.Text>
      <PriorityBinding FallbackValue="defaultvalue">
        <Binding Path="SlowestDP" IsAsync="True"/>
        <Binding Path="SlowerDP" IsAsync="True"/>
        <Binding Path="FastDP" />
      </PriorityBinding>
</TextBlock.Text>

10

Sử dụng các phương thức tĩnh của nhà máy với x: FactoryMethod

Khi bạn có một loại không có hàm tạo công khai nhưng một phương thức nhà máy tĩnh, bạn phải tạo loại đó trong mã trong XAML 2006. Với XAML 2009, bạn có thể sử dụng thuộc tính x: FactoryMethodx: Argument để truyền các giá trị đối số.

<!-- XAML 2006 -->
Guid id = Guid.NewGuid();

<!-- XAML 2009 -->
<Guid x:FactoryMethod="Guid.NewGuid" />

7

Thuộc tính "chú thích" nâng cao

Một điều không rõ ràng lắm là nội dung của một số thuộc tính mà chúng ta thường chỉ chứa văn bản. Nếu thuộc tính của một thành phần GUI thuộc loại Object, rất có khả năng bạn có thể, thay vì chỉ đặt văn bản, hãy thêm một bảng điều khiển theo nhu cầu của bạn bao gồm một bộ điều khiển.

Một ví dụ về điều này là MenuItem, nơi Header tính (thường chỉ chứa văn bản) có thể chứa một tập hợp các phần tử gui được bọc trong một điều khiển bảng điều khiển (hoặc chỉ một phần tử gui nếu bạn chỉ cần một phần tử).

Cũng lưu ý các thuộc Icontính trên MenuItem. Cái này thường chứa một phần tử Image, nhưng cái này cũng có thể chứa bất cứ thứ gì!

<MenuItem Name="MyMenuItem" Click="MyMenuItem_Click">
  <MenuItem.Icon>
    <Button Click="Button1_Click">i</Button>
  </MenuItem.Icon>
  <MenuItem.Header>
     <StackPanel Orientation="Horizontal" >
        <Label>My text</Label>
        <Button Click="Button2_Click">ClickMe!</Button>
     </StackPanel>
  </MenuItem.Header>
</MenuItem>

7

Bộ chuyển đổi XAML

Danh sách sau đây cho thấy các trình chuyển đổi được phát triển bởi cộng đồng WPF để chuyển đổi các định dạng khác nhau sang XAML hoặc ngược lại.

Plugin Adobe Illustrator XAML

Chuyển đổi Adobe Photoshop sang XAML

Trình xuất XAML của Blender

Plugin xuất XwL Lightwave

Xuất khẩu Visio XAML

Chuyển đổi 3D Studio Max sang XAML

Chuyển đổi Maya sang XAML

Chuyển đổi Flash sang XAML

Chuyển đổi SVG sang XAML

Chuyển đổi WMF / EMF sang XAML


cũng rất hữu ích: GridLạngConverter, BooleanToVisibilityConverter, AlternationConverter tất cả trong System.Windows.Controls
Maciek wiszczowski

6

Các loại tích hợp

Nếu bạn muốn thêm các đối tượng của các loại đơn giản như chuỗi hoặc gấp đôi vào một từ điển tài nguyên ngày hôm nay, bạn cần ánh xạ các không gian tên clr cần thiết vào một không gian tên XML. Trong XAML 2009, chúng tôi có rất nhiều loại đơn giản được bao gồm trong ngôn ngữ XAML.

<!-- XAML 2006 -->
<sys:String xmlns:sys="clr-namespace:System;assembly=mscorlib >Test</sys:String>

<!-- XAML 2009 -->
<x:String>Test</x:String>

Các loại sau đây được bao gồm trong ngôn ngữ XAML:

<x:Object/> 
<x:Boolean/> 
<x:Char/> 
<x:String/> 
<x:Decimal/> 
<x:Single/> 
<x:Double/> 
<x:Int16/> 
<x:Int32/> 
<x:Int64/> 
<x:TimeSpan/> 
<x:Uri/> 
<x:Byte/> 
<x:Array/> 
<x:List/> 
<x:Dictionary/> 

Điều này không hoạt động nếu sử dụng WPF để xử lý XAML. msdn.microsoft.com/en-us/l
Library / ee792007.aspx

6

Tham chiếu đối tượng dễ dàng với {x: Reference}

Nếu bạn muốn tạo một tham chiếu đối tượng ngày hôm nay, bạn cần thực hiện một cơ sở dữ liệu và khai báo nguồn với ElementName. Trong XAML 2009, bạn có thể sử dụng tiện ích mở rộng đánh dấu {x: Reference} mới

<!-- XAML 2006 -->
<Label Target="{Binding ElementName=firstName}">FirstName</Label>
<TextBox x:Name="firstName" />

<!-- XAML 2009 -->
<Label Target="{x:Reference firstName}">FirstName</Label>
<TextBox x:Name="firstName" />

Điều đáng chú ý là mặc dù x:Referencelà một tính năng ngôn ngữ XAML 2009, nhưng có một số tình huống nó cũng sẽ hoạt động trong XAML được biên dịch. Tuy nhiên, nó không hoạt động ở mọi nơi và nó có thể phá vỡ quan điểm của nhà thiết kế XAML.
Mike Strobel

1
@MikeStrobel: Nó hoạt động khá nhiều ở mọi nơi, và tôi không thể quan tâm đến việc các nhà thiết kế phá vỡ.
HB

6

Sử dụng màu hệ thống

<Border Background="{DynamicResource {x:Static SystemColors.InactiveBorderBrushKey}}"/>

3
Việc chỉ định nó là DynamicResource rất quan trọng vì người dùng có thể thay đổi màu hệ thống trong khi ứng dụng của bạn đang chạy.
M. Dudley

3

Hỗ trợ cho các khóa từ điển tùy ý

Trong XAML 2006, tất cả x: Giá trị khóa rõ ràng được coi là chuỗi. Trong XAML 2009, bạn có thể xác định bất kỳ loại khóa nào bạn thích bằng cách viết khóa trong ElementSyntax.

<!-- XAML 2006 -->
<StreamGeometry x:Key="CheckGeometry">M 0 0 L 12 8 l 9 12 z</StreamGeometry>

<!-- XAML 2009 -->
<StreamGeometry>M 0 0 L 12 8 l 9 12 z
    <x:Key><x:Double>10.0</x:Double></x:Key>
</StreamGeometry>

2

Đặt xác thựcError theo mã

Một ValidatioRule trong BindingExpression chỉ kích hoạt, khi phía đích của ràng buộc thay đổi. Nếu bạn muốn đặt lỗi xác thực theo mã, bạn có thể sử dụng đoạn mã sau.

Đặt lỗi xác thực

ValidationError validationError = 
    new ValidationError(regexValidationRule, 
    textBox.GetBindingExpression(TextBox.TextProperty));

validationError.ErrorContent = "This is not a valid e-mail address";

Validation.MarkInvalid(
    textBox.GetBindingExpression(TextBox.TextProperty), 
    validationError);

Xóa lỗi xác nhận

Validation.ClearInvalid(textBox.GetBindingExpression(TextBox.TextProperty));

2

Khả năng nhét (các) UIE bổ sung vào TextBlock

Tôi không biết làm thế nào hữu ích (mặc dù nó được coi là ẩn) nhưng điều này chắc chắn khiến tôi mất cảnh giác khi lần đầu tiên tôi gặp phải nó :

<Grid x:Name="LayoutRoot">
    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
        <Grid>
            <Rectangle Fill="AliceBlue" Width="25" Height="25"/>
        </Grid>
    </TextBlock>
</Grid>

Bạn có thể lập luận rằng xaml sau đây có thể hữu ích (nghĩa là đặt một hình ảnh ở cuối một số văn bản):

<Grid>
    <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="Hello World">
        <TextBlock.Resources>
            <DrawingBrush x:Key="exclamationPoint" Stretch="Uniform">
                <DrawingBrush.Drawing>
                    <DrawingGroup>
                        <DrawingGroup.Children>
                            <GeometryDrawing Brush="#FF375CE2" Geometry="F1 M 7.968,58.164L 0,58.164L 1.914,49.921L 9.882,49.921L 7.968,58.164 Z M 21.796,0L 11.054,42.148L 4.403,42.148L 13.049,0L 21.796,0 Z "/>
                        </DrawingGroup.Children>
                    </DrawingGroup>
                </DrawingBrush.Drawing>
            </DrawingBrush>
        </TextBlock.Resources>
        <Grid>
            <Rectangle Width="100" Height="100" Fill="{StaticResource exclamationPoint}"/>
        </Grid>
    </TextBlock>
</Grid>

Xaml ở trên biểu hiện như sau:

Chào thế giới


1

Gỡ lỗi hoạt hình

Lỗi thông thường

Nếu bạn gặp lỗi sau: Không thể tạo hiệu ứng '(0). (1)' trên một đối tượng bất biến. có thể là bạn đang gặp phải một trong những hạn chế sau:

  • Bạn đang tạo hiệu ứng thuộc tính phụ thuộc mà không đặt giá trị cục bộ
  • Bạn đang tạo hiệu ứng cho một thuộc tính phụ thuộc có giá trị hiện tại được xác định trong một cụm khác không được hợp nhất vào từ điển tài nguyên.
  • Bạn đang tạo hiệu ứng cho một giá trị hiện đang là cơ sở dữ liệu

1

Ràng buộc mà không có INotifyPropertyChanged hoặc DependencyProperies

Như đã thảo luận ở đây, bạn có thể liên kết một thuộc tính đối tượng CLR đơn giản mà không cần INotifyPropertyChanged, và nó sẽ chỉ hoạt động .

Đây là Forumpost tôi đang đề cập đến.

Trích dẫn:

[...] Công cụ liên kết dữ liệu của WPF sẽ liên kết dữ liệu với đối tượng PropertyDescriptor bao bọc thuộc tính nguồn nếu đối tượng nguồn là đối tượng CLR đơn giản và không triển khai giao diện INotifyPropertyChanged. Và công cụ liên kết dữ liệu sẽ cố gắng đăng ký vào sự kiện thay đổi thuộc tính thông qua phương thức PropertyDescriptor.AddValueChanged (). Và khi phần tử ràng buộc dữ liệu đích thay đổi giá trị thuộc tính, công cụ liên kết dữ liệu sẽ gọi phương thức PropertyDescriptor.SetValue () để chuyển giá trị đã thay đổi trở lại thuộc tính nguồn và đồng thời sẽ tăng sự kiện ValueChanged để thông báo cho các thuê bao khác (trong trường hợp này, những người đăng ký khác sẽ là TextBlocks trong ListBox.

Và nếu bạn đang triển khai INotifyPropertyChanged, bạn hoàn toàn chịu trách nhiệm triển khai thông báo thay đổi trong mỗi tập hợp các thuộc tính cần được liên kết dữ liệu với UI. Nếu không, thay đổi sẽ không được đồng bộ hóa như bạn mong đợi. [...]

Dưới đây là một bài viết tuyệt vời và chi tiết về chủ đề này.

Lưu ý điều này chỉ hoạt động khi sử dụng ràng buộc . Nếu bạn cập nhật các giá trị từ mã , thay đổi sẽ không được thông báo . [...]

Việc triển khai INotifyPropertyChanged có thể là một chút công việc phát triển tẻ nhạt. Tuy nhiên, bạn sẽ cần cân nhắc công việc đó với thời gian chạy (bộ nhớ và CPU) của ứng dụng WPF của bạn. Tự thực hiện INPC sẽ tiết kiệm CPU và bộ nhớ thời gian chạy .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.