Fitur tersembunyi WPF dan XAML?

123

Berikut adalah sejumlah besar fitur tersembunyi yang dibahas untuk berbagai bahasa. Sekarang saya penasaran dengan beberapa fitur tersembunyi dari XAML dan WPF?

Satu yang saya temukan adalah acara klik header dari ListView

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

Properti GridViewColumnHeader.Click tidak terdaftar.

Beberapa fitur yang relevan sejauh ini:

Lihat juga:

  1. Fitur tersembunyi dari C #
  2. Fitur tersembunyi dari Python
  3. Fitur tersembunyi ASP.NET
  4. Fitur tersembunyi Perl
  5. Fitur tersembunyi dari Java
  6. Fitur tersembunyi dari VB.NET
  7. Fitur tersembunyi dari PHP
  8. Fitur Tersembunyi dari Ruby
  9. Fitur tersembunyi dari C
  10. Dan seterusnya........
Sauron
sumber
7
Lihat di sini msdn.microsoft.com/en-us/library/… . Acara klik diwarisi dari ButtonBase. Apa yang Anda gambarkan dilampirkan Acara, konsep yang cukup kuat di WPF ( msdn.microsoft.com/en-us/library/bb613550.aspx ). Dengan cara ini Anda bisa melakukan <Grid Button.Click> dengan 100 tombol pada satu grid dan hanya 1 handler.
Sorskoot
1
Awalnya saya seperti "oh, ini dia lagi," tapi kemudian saya belajar sesuatu dari tanggapannya jadi saya mengambil semuanya kembali: o: o
Sam Harwell
1
harus komunitas wiki
tsilb
2
@tsilb Saya tidak berpikir itu harus wiki komunitas, lihat tautan ini meta.stackexchange.com/questions/392/…
Prashant Cholachagudda

Jawaban:

87

Multibinding (dikombinasikan dengan StringFormat):

<TextBlock>
  <TextBlock.Text>
    <MultiBinding StringFormat="{}{0}, {1}">
      <Binding Path="LastName" />
      <Binding Path="FirstName" />
    </MultiBinding>
  </TextBlock.Text>
</TextBlock>
Julien Poulin
sumber
1
mengagumkan :-) kecuali Anda menggunakan silverlight 4 atau sebelumnya. semoga berhasil untuk v5
Simon_Weaver
5
Ini bagus, tapi saya akan tergoda untuk TIDAK melakukannya. Jika saya perlu membangun string, saya akan mengklasifikasikannya sebagai logika dan ingin menguji unit output. Hal-hal seperti ini terkadang lebih baik dalam model tampilan sebagai string.Format ().
Iain Holder
58

Ada juga trik PresentationTraceSources.TraceLevel untuk men-debug apa yang terjadi dengan binding dalam skenario tertentu. Yang harus Anda lakukan adalah merujuk namespace System.Diagnostics di rakitan WindowsBase

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

lalu tambahkan yang berikut ke ekspresi binding:

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

Log akan seperti ini:

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 
idursun
sumber
4
Di VisualStudio 2010 Anda perlu mengatur tingkat pengaturan jejak ke peringatan! Lihat stackoverflow.com/questions/2802662/…
WaltiD
44

3.5sp1 memperkenalkan TargetNullValue ke binding. Ini akan menyetel properti terikat ke Null jika nilai dimasukkan dan jika properti Anda adalah Null itu akan menampilkan nilai ini.

<TextBox Text="{Binding Total, TargetNullValue=$0.00}" />
Bryan Anderson
sumber
44

3.5sp1 memperkenalkan StringFormat ke dalam ekspresi yang mengikat, misalnya

<TextBox Text="{Binding Date, StringFormat='{}{0:MM/dd/yyyy}'}" />
Bryan Anderson
sumber
Saya tidak dapat mengungkapkan dengan kata-kata betapa saya sangat menyukai fitur itu. Saya benci memiliki banyak konverter nilai yang bertebaran.
Rob
Ya, dengan mudah salah satu fitur penghemat waktu paling banyak ditambahkan. Terutama jika digabungkan dengan TargetNullValue banyak masalah yang hilang.
Bryan Anderson
6
Menempatkan tanda kutip tunggal di sekitar StringFormat harus menghapus beberapa peringatan kompiler -Text={Binding Date, StringFormat='{}{0:MM/dd/yyyy}'}"
Ryan Versaw
Tenang rasanya, saya sudah terbiasa mengabaikannya.
Bryan Anderson
1
Saya mencoba menyampaikan bahwa string pemformatan arbitrer apa pun akan berfungsi. Saya yakin versi internasionalisasi adalah StringFormat = '{} {0: d}' dalam kasus ini.
Bryan Anderson
29

Terkadang Anda mendapatkan string yang terlalu panjang untuk ditampilkan pada label. Dalam hal ini kita dapat menggunakan TextTrimmingproperti TextBlockuntuk menunjukkan Elips

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

Tautan MSDN

Prashant
sumber
Pertimbangkan untuk menambahkan tooltip dalam kasus seperti ini: tranxcoder.wordpress.com/2008/10/12/…
surfing
27

Menambahkan efek Aero ke Window

  <Window.Resources>
    <ResourceDictionary Source="/PresentationFramework.Aero, Version=3.0.0.0, Culture=neutral, 
        PublicKeyToken=31bf3856ad364e35, ProcessorArchitecture=MSIL;component/themes/aero.normalcolor.xaml" />
</Window.Resources>
Sauron
sumber
1
Menambahkan kode tetapi tetap tidak menambahkan efek Aero. Apakah saya melewatkan sesuatu?
Elmo
21

Generik di XAML dengan x: TypeArguments

Jika Anda ingin menggunakan ObservableCollection di XAML, Anda perlu membuat tipe yang berasal dari ObservableCollection karena Anda tidak bisa mendeklarasikannya di XAML. Dengan XAML 2009 Anda dapat menggunakan atribut x: TypeArguments untuk menentukan tipe tipe generik.

<!-- 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 />
Sauron
sumber
1
Sayangnya, x: TypeArguments hanya tersedia dalam file xaml longgar dan tidak dikompilasi :(
kevindaub
Ya, xaml longgar saja :( Untuk sebagian besar pengembang WPF, XAML2009 tidak berguna.
Grigory
19

Tampilkan Keterangan Alat pada kontrol yang dinonaktifkan

Wpf memungkinkan untuk menampilkan tooltip pada kontrol, jika dalam keadaan nonaktif.

Sebagai contoh

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

Penggunaan Konstruktor Non-Default dengan x: Argumen

Dalam XAML 2006 objek harus memiliki konstruktor default publik untuk menggunakannya. Di XAML 2009 Anda dapat mengirimkan argumen konstruktor dengan menggunakan sintaks x: Arguments.

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

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

Bukan fitur tersembunyi tetapi dengan WPF / XAML Anda mendapatkan Bea Stollnitz dan Josh Smith . Pemrograman Ratu dan Raja WPF / XAML.

Bryan Anderson
sumber
3
Apakah Karl itu? Dongkrak? Atau Joker?
cplotts
18

Ekstensi markup dan properti terlampir adalah fitur favorit saya, mereka memungkinkan Anda untuk memperluas "kosakata" XAML dengan cara yang sangat elegan.

Ekstensi markup

<!-- 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}"/>

Properti terlampir

<!-- 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">

...

Sumber untuk GridViewSort (btw, ini menggunakan GridViewColumnHeader.Clickacara yang disebutkan oleh Ortus)

Thomas Levesque
sumber
Apakah sumber WinUtil.EnableAeroGlasstersedia di suatu tempat?
Oskar
Ya, tapi sudah banyak berubah sejak saya memposting ini ... Sekarang ada 2 properti, EnableBlur dan GlassFrameMargins. Anda dapat menemukan kodenya di sini: projets.developpez.com/projects/dvp-net/repository/entry/trunk/…
Thomas Levesque
15

Anda bisa merujuk ke tipe bertingkat di XAML menggunakan tanda plus ( +). Misalnya, jika kita memiliki kelas ini:

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

Kita bisa merujuk ke SomeValueXAML menggunakan sintaks berikut:

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

Sintaks ini tidak didokumentasikan di MSDN , dan tidak didukung secara resmi. Seseorang bertanya tentang hal itu di forum MSDN, dan tampaknya itu merusak Desainer WPF VS2010. Ini telah dilaporkan di Microsoft Connect.

M. Dudley
sumber
14

Berbagi ukuran kisi ( inilah contoh yang bagus). Singkatnya, Anda dapat memiliki kolom kisi dan baris berbagi ukuran, bahkan di berbagai kisi. Ini akan sangat berharga bagi semua orang di luar sana yang menggunakan DataGrid tanpa perlu mengedit data di tempat.

Bryan Anderson
sumber
11

Pengikatan Prioritas . Memungkinkan Anda menggunakan asyn binding dalam urutan "pertama datang pertama kali":

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

Penggunaan Metode Pabrik Statis dengan x: FactoryMethod

Ketika Anda memiliki tipe yang tidak memiliki konstruktor publik tetapi metode pabrik statis Anda harus membuat tipe tersebut dalam kode di XAML 2006. Dengan XAML 2009 Anda dapat menggunakan atribut x: FactoryMethodx: Arguments untuk meneruskan nilai argumen.

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

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

Properti "teks" lanjutan

Hal lain yang tidak terlalu jelas adalah isi dari beberapa properti yang biasa kita gunakan hanya berisi teks. Jika properti elemen GUI berjenis Objek, kemungkinan besar Anda dapat, alih-alih hanya menyetel teks, menambahkan panel kebutuhan Anda yang menyertakan serangkaian kontrol.

Contohnya adalah MenuItem, di mana Headerproperti (yang biasanya hanya berisi teks) dapat berisi sekumpulan elemen gui yang dibungkus dalam kontrol panel (atau hanya satu elemen gui jika Anda hanya membutuhkan satu).

Perhatikan juga Iconproperti pada MenuItem. Ini biasanya berisi elemen Gambar, tetapi ini juga dapat berisi apa saja!

<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>
kagum
sumber
7

Pengonversi XAML

Daftar berikut menunjukkan konverter yang dikembangkan oleh komunitas WPF untuk mengonversi format yang berbeda ke XAML atau sebaliknya.

Plugin Ekspor Adobe Illustrator XAML

Konverter Adobe Photoshop ke XAML

Plugin Ekspor Blender XAML

Plugin Ekspor Lightwave XAML

Ekspor Visio XAML

Konverter 3D Studio Max ke XAML

Konverter Maya ke XAML

Flash ke XAML Converter

SVG ke XAML Converter

Konverter WMF / EMF ke XAML

Sauron
sumber
juga sangat berguna: GridLengthConverter, BooleanToVisibilityConverter, AlternationConverter semua di System.Windows.Controls
Maciek Świszczowski
6

Jenis Bawaan

Jika Anda ingin menambahkan objek berjenis sederhana seperti string atau double ke kamus sumber daya hari ini, Anda perlu memetakan ruang nama clr yang diperlukan ke ruang nama XML. Di XAML 2009 kami banyak tipe sederhana yang termasuk dalam bahasa XAML.

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

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

Jenis berikut ini termasuk ke dalam bahasa 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/> 
Sauron
sumber
Ini tidak berfungsi jika menggunakan WPF untuk memproses XAML. msdn.microsoft.com/en-us/library/ee792007.aspx
scobi
6

Referensi Objek Mudah dengan {x: Referensi}

Jika Anda ingin membuat referensi objek hari ini, Anda perlu melakukan penyatuan data dan mendeklarasikan sumber dengan ElementName. Di XAML 2009 Anda dapat menggunakan ekstensi markup {x: Reference} yang baru

<!-- 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" />
Sauron
sumber
Perlu dicatat bahwa meskipun x:Referencemerupakan fitur bahasa XAML 2009, ada beberapa skenario di mana ia akan bekerja di XAML yang telah dikompilasi juga. Namun, ini tidak berfungsi di semua tempat, dan dapat merusak tampilan desainer XAML.
Mike Strobel
1
@MikeStrobel: Ini bekerja cukup banyak di mana-mana, dan saya tidak peduli tentang kerusakan desainer.
HB
6

Penggunaan Warna Sistem

<Border Background="{DynamicResource {x:Static SystemColors.InactiveBorderBrushKey}}"/>
Lihat Tajam
sumber
3
Menentukannya sebagai DynamicResource penting karena pengguna dapat mengubah warna sistem saat aplikasi Anda berjalan.
M. Dudley
3

Dukungan untuk Tombol Kamus Sewenang-wenang

Dalam XAML 2006 semua x eksplisit: Nilai kunci diperlakukan sebagai string. Di XAML 2009 Anda dapat menentukan semua jenis kunci yang Anda suka dengan menulis kunci di 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>
Sauron
sumber
2

Setel ValidationError menurut Kode

ValidatioRule dalam BindingExpression hanya terpicu, saat sisi target pengikatan berubah. Jika Anda ingin mengatur kesalahan validasi dengan kode Anda dapat menggunakan potongan berikut.

Atur kesalahan validasi

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);

Hapus kesalahan validasi

Validation.ClearInvalid(textBox.GetBindingExpression(TextBox.TextProperty));
Sauron
sumber
2

Kemampuan untuk Menjejali Elemen UI ke dalam TextBlock

Saya tidak tahu seberapa berguna (meskipun memenuhi syarat sebagai tersembunyi) ini ... tetapi pasti membuat saya lengah ketika saya pertama kali bertemu dengannya :

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

Anda dapat berargumen bahwa xaml berikut dapat berguna (yaitu meletakkan grafik di akhir beberapa teks):

<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 di atas menghasilkan seperti berikut:

Halo Dunia

cplotts
sumber
1

Debugging Animasi

Kesalahan Umum

Jika Anda mendapatkan error berikut: Tidak dapat menganimasikan '(0). (1)' pada instance objek yang tidak dapat diubah. mungkin Anda mengalami salah satu batasan berikut:

  • Anda menganimasikan properti dependensi tanpa menyetel nilai lokal
  • Anda menganimasikan properti ketergantungan yang nilainya saat ini ditentukan di rakitan lain yang tidak digabungkan ke dalam kamus sumber daya.
  • Anda menganimasikan nilai yang saat ini berada di databound
Sauron
sumber
1

Binding tanpa INotifyPropertyChanged atau DependencyProperties

Seperti yang dibahas di sini, Anda bisa mengikat properti objek CLR biasa tanpa INotifyPropertyChanged, dan itu hanya akan berfungsi .

Ini adalah Forumpost yang saya maksud.

Mengutip:

[...] Mesin pengikat data WPF akan mengikat data ke instance PropertyDescriptor yang membungkus properti sumber jika objek sumber adalah objek CLR biasa dan tidak mengimplementasikan antarmuka INotifyPropertyChanged. Dan mesin pengikat data akan mencoba berlangganan ke peristiwa properti yang diubah melalui metode PropertyDescriptor.AddValueChanged (). Dan ketika elemen data terikat target mengubah nilai properti, mesin data binding akan memanggil metode PropertyDescriptor.SetValue () untuk mentransfer nilai yang diubah kembali ke properti sumber, dan secara bersamaan akan meningkatkan peristiwa ValueChanged untuk memberi tahu pelanggan lain (dalam hal ini, pelanggan lain akan menjadi TextBlocks dalam ListBox.

Dan jika Anda mengimplementasikan INotifyPropertyChanged, Anda bertanggung jawab penuh untuk mengimplementasikan notifikasi perubahan di setiap penyetel properti yang perlu datanya terikat ke UI. Jika tidak, perubahan tidak akan disinkronkan seperti yang Anda harapkan. [...]

Berikut adalah artikel bagus dan terperinci lainnya tentang masalah ini.

Perhatikan bahwa ini hanya berfungsi saat menggunakan penjilidan . Jika Anda memperbarui nilai dari kode , perubahan tidak akan diberitahukan . [...]

Menerapkan INotifyPropertyChanged bisa menjadi pekerjaan pengembangan yang cukup membosankan. Namun, Anda harus mempertimbangkan pekerjaan itu dengan jejak runtime (memori dan CPU) aplikasi WPF Anda. Menerapkan INPC sendiri akan menghemat waktu proses CPU dan memori .

UrbanEsc
sumber