WPF ve XAML'nin gizli özellikleri?


123

İşte çeşitli diller için tartışılan çok sayıda gizli özellik. Şimdi XAML ve WPF'nin bazı gizli özelliklerini merak ediyorum?

Bulduğum bir tanesi, ListView'in başlık tıklama olayı

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

GridViewColumnHeader.Click özelliği listelenmemiş.

Şimdiye kadarki alakalı özelliklerden bazıları:

Ayrıca bakınız:

  1. C # 'ın gizli özellikleri
  2. Python'un gizli özellikleri
  3. ASP.NET'in gizli özellikleri
  4. Perl'in gizli özellikleri
  5. Java'nın gizli özellikleri
  6. VB.NET'in gizli özellikleri
  7. PHP'nin gizli özellikleri
  8. Ruby'nin gizli özellikleri
  9. C'nin gizli özellikleri
  10. Ve bunun gibi........

7
Burada msdn.microsoft.com/en-us/library/… bir göz atın . Click olayı ButtonBase'den miras alınır. Açıkladığınız şey, WPF'de oldukça güçlü bir konsept olan ekli Olaylar'dır ( msdn.microsoft.com/en-us/library/bb613550.aspx ). Bu şekilde, bir ızgara üzerinde 100 düğme ve yalnızca 1 işleyici ile <Grid Button.Click> yapabilirsiniz.
Sorskoot

1
İlk başta "ah, işte yine başlıyoruz" gibiydim ama sonra yanıtlarda bir şeyler öğrendim, bu yüzden hepsini geri alıyorum: o: o
Sam Harwell

1
topluluk wiki olmalıdır
tsilb

2
@tsilb Topluluk wiki olması gerektiğini düşünmüyorum, şu bağlantıya bir bak: meta.stackexchange.com/questions/392/…
Prashant Cholachagudda

Yanıtlar:


87

Çoklu- (StringFormat ile birlikte):

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

1
silverlight 4 veya önceki bir sürümü kullanmadığınız sürece harika :-). v5 için parmaklar geçti
Simon_Weaver

5
Bu harika, ama bunu yapmamak için cazip olurum. Bir dizge oluşturmam gerekirse, bunu mantık olarak sınıflandırır ve çıktıyı birim test etmek isterim. Bunun gibi şeyler, görünüm modelinde bir dizge olarak bazen daha iyidir.
Iain Holder

58

Ayrıca, belirli bir senaryoda bağlamalarla neler olup bittiğini ayıklamak için PresentationTraceSources.TraceLevel hile de vardır. Tek yapmanız gereken, WindowsBase derlemesinde System.Diagnostics ad alanına başvurmaktır.

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

ve ardından bağlama ifadesine şunu ekleyin:

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

Günlük şu şekilde olacaktır:

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
VisualStudio 2010'da, izleme ayarlarının seviyesini uyarı olarak ayarlamanız gerekir! Stackoverflow.com/questions/2802662/… sayfasına
WaltiD

44

3.5sp1, bağlamalara TargetNullValue özelliğini getirdi. Bu, değer girilirse, bound özelliği Null olarak ayarlanır ve mülkünüz Null ise bu değeri görüntüler.

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

44

3.5sp1, StringFormat'ı bağlama ifadelerine dahil etti, ör.

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

Bu özelliği ne kadar sevdiğimi kelimelere dökemiyorum. Etrafta tonlarca değer dönüştürücünün durmasından nefret ediyordum.
Rob

Evet, kolayca eklenen en çok zaman kazandıran özelliklerden biri. Özellikle TargetNullValue ile birleştirildiğinde pek çok sorun ortadan kalkar.
Bryan Anderson

6
StringFormat'ın etrafına tek tırnak işareti koymak bazı derleyici uyarılarını kaldırmalıdır -Text={Binding Date, StringFormat='{}{0:MM/dd/yyyy}'}"
Ryan Versaw

Bilmek güzel, onları görmezden gelmeye alıştım.
Bryan Anderson

1
Herhangi bir rasgele biçimlendirme dizesinin işe yarayacağını aktarmaya çalışıyordum. Uluslararasılaştırılmış sürümün bu durumda StringFormat = '{} {0: d}' olacağına inanıyorum.
Bryan Anderson


27

Pencereye Aero efekti ekleme

  <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
Kodu eklendi ancak yine de Aero efektini eklemiyor. Bir şey mi kaçırıyorum?
Elmo

21

X: TypeArguments ile XAML'de jenerikler

XAML'de bir ObservableCollection kullanmak istiyorsanız, ObservableCollection'dan türetilen bir tür oluşturmanız gerekir, çünkü bunu XAML'de bildiremezsiniz. XAML 2009 ile, genel bir türün türünü tanımlamak için x: TypeArguments özniteliğini kullanabilirsiniz.

<!-- 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
Ne yazık ki, x: TypeArguments yalnızca gevşek xaml dosyalarında mevcut ve derlenmemiş :(
kevindaub

Evet, yalnızca xaml :( WPF geliştiricilerinin çoğu için XAML2009 işe yaramaz.
Grigory

19

Araç İpucunu devre dışı bırakılmış bir denetimde göster

Wpf, devre dışı durumdaysa bir denetimde araç ipucunun gösterilmesine izin verir.

Örneğin

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

19

Varsayılan Olmayan Oluşturucuların x: Arguments ile Kullanımı

XAML 2006'da nesneler, bunları kullanmak için genel bir varsayılan kurucuya sahip olmalıdır. XAML 2009'da x: Arguments sözdizimini kullanarak yapıcı bağımsız değişkenlerini iletebilirsiniz.

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

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


18

İşaretleme uzantıları ve ekli özellikler en sevdiğim özelliklerdir, XAML "sözlüğünü" çok zarif bir şekilde genişletmenizi sağlarlar.

İşaretleme uzantıları

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

Ekli özellikler

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

...

GridViewSort için kaynak (btw, GridViewColumnHeader.ClickOrtus tarafından bahsedilen olayı kullanır )


Kaynak bir WinUtil.EnableAeroGlassyerde mevcut mu?
Oskar

Evet, ama bunu yayınladığımdan beri çok değişti ... Şu anda 2 özellik var, EnableBlur ve GlassFrameMargins. Kodu burada bulabilirsiniz: projets.developpez.com/projects/dvp-net/repository/entry/trunk/…
Thomas Levesque

15

Artı işaretini ( +) kullanarak XAML'deki yuvalanmış türlere başvurabilirsiniz . Örneğin, bu sınıfa sahip olsaydık:

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

SomeValueAşağıdaki sözdizimini kullanarak XAML'de başvurabiliriz :

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

Bu sözdizimi MSDN'de belgelenmemiştir ve resmi olarak desteklenmemektedir. Birisi MSDN forumlarında bunu sordu ve görünüşe göre VS2010'un WPF Tasarımcısını bozuyor. Bu gelmiştir bildirilmiştir Microsoft Connect üzerinde.


14

Izgara boyutu paylaşımı ( işte iyi bir örnek). Uzun lafın kısası, farklı ızgaralarda bile ızgara sütunlarına ve satırlarının boyutlarını paylaşabilirsiniz. Bu, verileri yerinde düzenlemeye gerek kalmadan DataGrids kullanan tüm insanlar için paha biçilmez olacaktır.


11

PriorityBinding . Eşzamansız bağlamaları "ilk gelen ilk gösteri" sıralamasında kullanmanıza olanak tanır:

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

10

Statik Fabrika Yöntemlerinin x: FactoryMethod ile Kullanımı

Genel kurucusu olmayan ancak statik fabrika yöntemine sahip bir türe sahip olduğunuzda, bu türü XAML 2006'da kodda oluşturmanız gerekir. XAML 2009 ile, bağımsız değişken değerlerini geçirmek için x: FactoryMethodx: Arguments özniteliğini kullanabilirsiniz.

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

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

7

Gelişmiş "altyazı" özellikleri

Çok açık olmayan bir diğer şey ise, alışkın olduğumuz bazı özelliklerin içeriğinin sadece metin içermesidir. Bir GUI öğesinin özelliği Object türündeyse, yalnızca metni ayarlamak yerine, bir dizi denetim içeren bir ihtiyaç paneli eklemeniz çok olasıdır.

Bunun bir örneği, Header(normalde sadece metin içeren) özelliğin bir panel kontrolüne sarılmış bir dizi gui öğesi (veya yalnızca birine ihtiyacınız varsa yalnızca bir gui öğesi) içerebildiği MenuItem'dir .

Ayrıca IconMenuItem'deki özelliği not edin . Bu normalde bir Görüntü öğesi içerir, ancak bu aynı zamanda her şeyi içerebilir!

<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

ayrıca çok kullanışlı: GridLengthConverter, BooleanToVisibilityConverter, AlternationConverter hepsi System.Windows.Controls'de
Maciek Świszczowski

6

Yerleşik Tipler

Bugün bir kaynak sözlüğüne string veya double gibi basit türde nesneler eklemek istiyorsanız, gerekli clr-ad alanlarını XML ad alanlarıyla eşlemeniz gerekir. XAML 2009'da, XAML dilinde bulunan birçok basit türümüz var.

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

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

Aşağıdaki türler XAML diline dahil edilmiştir:

<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/> 

XAML'yi işlemek için WPF kullanılıyorsa bu işe yaramaz. msdn.microsoft.com/en-us/library/ee792007.aspx
scobi

6

{X: Reference} ile Kolay Nesne Referansları

Bugün bir nesne referansı oluşturmak istiyorsanız, bir veri bağlama yapmanız ve kaynağı bir ElementName ile bildirmeniz gerekir. XAML 2009'da yeni {x: Reference} biçimlendirme uzantısını kullanabilirsiniz

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

Bu süre belirterek It yetmeyecek x:Referencebuna da derlenmiş XAML çalışacak bazı senaryo vardır, bir XAML 2009 dil özelliğidir. Ancak, her yerde çalışmaz ve XAML tasarımcısı görünümünü bozabilir.
Mike Strobel

1
@MikeStrobel: Hemen hemen her yerde çalışıyor, aa ve tasarımcıların kırılması umurumda bile değil.
HB

6

Sistem Renkleri Kullanımı

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

3
Bunu DynamicResource olarak belirtmek önemlidir çünkü kullanıcı, uygulamanız çalışırken sistem renklerini değiştirebilir.
M Dudley

3

Keyfi Sözlük Anahtarları Desteği

XAML 2006'da tüm açık x: Anahtar değerleri dizeler olarak değerlendirildi. XAML 2009'da, anahtarı ElementSyntax'ta yazarak istediğiniz herhangi bir anahtar türünü tanımlayabilirsiniz.

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

Koda Göre Doğrulama Hatası Ayarlama

Bir BindingExpression'daki ValidatioRule, yalnızca bağlamanın hedef tarafı değiştiğinde tetiklenir. Koda göre bir doğrulama hatası ayarlamak istiyorsanız, aşağıdaki parçacığı kullanabilirsiniz.

Doğrulama hatasını ayarlayın

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

Doğrulama hatasını temizleyin

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

2

UIElement'leri bir TextBlock'a Doldurma Yeteneği

Bunun ne kadar yararlı olduğunu bilmiyorum (gizli olarak nitelendiriliyor) ... ama ilk karşılaştığımda beni kesinlikle hazırlıksız yakaladı :

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

Aşağıdaki xaml'nin yararlı olabileceğini iddia edebilirsiniz (yani, bir metnin sonuna bir grafik koymak):

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

Yukarıdaki xaml şu şekilde işler:

Selam Dünya


1

Animasyonlarda Hata Ayıklama

Genel hatalar

Aşağıdaki hatayı alırsanız: Değişmez bir nesne örneğinde '(0). (1)' canlandırılamaz. aşağıdaki sınırlamalardan biriyle karşılaşmış olabilirsiniz:

  • Yerel bir değer belirlemeden bir bağımlılık özelliğine animasyon uyguluyorsunuz
  • Geçerli değeri kaynak sözlüğüyle birleştirilmemiş başka bir derlemede tanımlanan bir bağımlılık özelliğine animasyon uyguluyorsunuz.
  • Şu anda veri bağlantılı bir değere animasyon uyguluyorsunuz

1

INotifyPropertyChanged veya DependencyProperties olmadan Bağlama

Bahsedildiği gibi burada INotifyPropertyChanged olmadan, bir düz CLR nesne özelliği bağlayabilirsiniz ve bu olacak sadece iş .

İşte bahsettiğim Forum yazısı .

Alıntı:

[...] WPF'nin veri bağlama motoru, kaynak nesne düz bir CLR nesnesiyse ve INotifyPropertyChanged arabirimini uygulamıyorsa, kaynak özelliğini saran PropertyDescriptor örneğine veri bağlanacaktır. Ve veri bağlama motoru, PropertyDescriptor.AddValueChanged () yöntemi aracılığıyla özellik değiştirildi olayına abone olmaya çalışacaktır. Ve hedef veriye bağlı öğe özellik değerlerini değiştirdiğinde, veri bağlama motoru değiştirilen değeri kaynak özelliğine geri aktarmak için PropertyDescriptor.SetValue () yöntemini çağırır ve eşzamanlı olarak diğer aboneleri bilgilendirmek için ValueChanged olayını yükseltir (bu örnekte, diğer aboneler ListBox içindeki TextBlock'lar olacaktır.

Ve INotifyPropertyChanged uyguluyorsanız, kullanıcı arayüzüne veri bağlanması gereken özelliklerin her ayarlayıcısında değişiklik bildirimini uygulamaktan tamamen siz sorumlusunuz. Aksi takdirde, değişiklik beklediğiniz gibi senkronize edilmeyecektir. [...]

İşte konuyla ilgili harika ve ayrıntılı bir makale daha .

Bunun yalnızca ciltleme kullanılırken çalıştığını unutmayın . Değerleri koddan güncellerseniz, değişiklik bildirilmez . [...]

INotifyPropertyChanged uygulamasının uygulanması oldukça sıkıcı bir geliştirme çalışması olabilir. Ancak, bu çalışmayı WPF uygulamanızın çalışma zamanı ayak izine (bellek ve CPU) göre tartmanız gerekir. INPC'yi kendiniz uygulamak, çalışma zamanı CPU'sundan ve belleğinden tasarruf sağlayacaktır .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.