Скрытые функции WPF и XAML? - программирование

Скрытые функции WPF и XAML?

Здесь представлено большое количество скрытых функций для разных языков. Теперь мне интересно узнать некоторые скрытые возможности XAML и WPF?

Одно, которое я нашел, - это событие щелчка заголовка ListView

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

Свойство GridViewColumnHeader.Click не указано.

Некоторые из важных функций:

См. также:

4b9b3361

Ответ 1

Multibinding (в сочетании с StringFormat):

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

Ответ 2

Существует также метод PresentationTraceSources.TraceLevel для отладки того, что происходит с привязками в любом конкретном сценарии. Все, что вам нужно сделать, это ссылаться на пространство имен System.Diagnostics в сборке WindowsBase

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

а затем добавьте следующее выражение привязки:

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

Журнал будет таким:

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 

Ответ 3

3.5sp1 ввел StringFormat в выражения привязки, например.

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

Ответ 4

3.5sp1 ввел TargetNullValue в привязки. Это установит свойство bound на Null, если значение введено, и если ваше свойство имеет значение Null, оно отобразит это значение.

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

Ответ 5

Иногда вы получаете строку, которая слишком длинна для отображения на ярлыке. В этом случае мы можем использовать свойство TextTrimming TextBlock для отображения эллипсов

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

Ссылка MSDN

Ответ 6

Добавление эффекта Aero к окну

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

Ответ 7

Дженерики в XAML с x: TypeArguments

Если вы хотите использовать ObservableCollection в XAML, вам нужно создать тип, который происходит из ObservableCollection, потому что вы не можете объявить его в XAML. С XAML 2009 вы можете использовать атрибут x: TypeArguments для определения типа родового типа.

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

Ответ 8

Показать всплывающую подсказку об отключенном элементе управления

Wpf позволяет отображать всплывающую подсказку на элементе управления, если он находится в отключенном состоянии.

Например

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

Ответ 9

Использование конструкторов, отличных от Default, с аргументами x: Аргументы

В XAML 2006 объекты должны иметь стандартный конструктор по умолчанию для их использования. В XAML 2009 вы можете передавать аргументы конструктора с помощью синтаксиса x: Arguments.

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

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

Ответ 10

Не действительно скрытая функция, но с WPF/XAML вы получаете Bea Stollnitz и Джош Смит. Королева и король WPF/XAML.

Ответ 11

Расширения разметки и прикрепленные свойства - мои любимые функции, они позволяют вам значительно расширить словарь "XAML".

Расширения разметки

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

Прикрепленные свойства

<!-- 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 (кстати, он использует событие GridViewColumnHeader.Click, упомянутое Ortus)

Ответ 12

Вы можете ссылаться на вложенные типы в XAML, используя знак плюса (+). Например, если бы у нас был этот класс:

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

Мы могли бы ссылаться на SomeValue в XAML, используя следующий синтаксис:

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

Этот синтаксис не документирован в MSDN, и он официально не поддерживается. Кто-то спросил об этом на форумах MSDN, и, по-видимому, он разбивает VS2010 WPF Designer. Он был отправлен в Microsoft Connect.

Ответ 14

PriorityBinding. Позволяет использовать привязки asyn в порядке "first come first show":

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

Ответ 15

Использование статических Factory методов с x: FactoryMethod

Если у вас есть тип, у которого нет открытого конструктора, а статический метод Factory, вам нужно было создать этот тип кода в XAML 2006. С XAML 2009 вы можете использовать атрибут x: FactoryMethodx: Arguments для передачи значений аргументов.

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

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

Ответ 16

Расширенные свойства "подпись"

Еще одна вещь, которая не совсем ясна, - это содержимое некоторых свойств, к которым мы привыкли, содержит только текст. Если свойство элемента GUI имеет тип Object, очень вероятно, что вместо простого добавления текста вы можете добавить панель, в которую входит набор элементов управления.

Примером этого является MenuItem, где свойство Header (обычно содержащее текст) может содержать набор элементов gui, завернутых в панель управления (или только один элемент gui, если вам нужен только один).

Также обратите внимание на свойство Icon в MenuItem. Обычно это элемент изображения, но это также может содержать что угодно!

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

Ответ 17

Преобразователи XAML

В следующем списке представлены конвертеры, разработанные сообществом WPF для преобразования различных форматов в XAML или наоборот.

Плагин экспорта Adobe Illustrator XAML

Adobe Photoshop для XAML Converter

Blender XAML Export Plugin

Lightwave XAML Export Plugin

Экспорт Visio XAML

Конвертер 3D Studio Max в XAML

Конвертер Maya в XAML

Flash to XAML Converter

Конвертер SVG в XAML

WMF/EMF в конвертер XAML

Ответ 18

Встроенные типы

Если вы хотите добавить объекты простых типов, например string или double, в словарь ресурсов сегодня, вам нужно сопоставить необходимые пространства имен clr-имен с пространствами имен XML. В XAML 2009 мы много простых типов, которые включены в язык XAML.

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

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

В язык 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/> 

Ответ 19

Ссылки на простые объекты с помощью {x: Ссылка}

Если вы хотите создать ссылку на объект сегодня, вам нужно выполнить привязку данных и объявить источник с ElementName. В XAML 2009 вы можете использовать новое расширение разметки {x: Reference}

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

Ответ 20

Использование системных цветов

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

Ответ 21

Поддержка произвольных словарных ключей

В XAML 2006 все явное значение x: Key рассматривались как строки. В XAML 2009 вы можете определить любой тип ключа, который вам нравится, написав ключ в 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>

Ответ 22

Установите значение ValidationError по коду

ValidatioRule в BindingExpression только запускает, когда целевая сторона привязки изменяется. Если вы хотите установить ошибку проверки по коду, вы можете использовать следующий фрагмент.

Задайте ошибку проверки

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

Очистить ошибку проверки

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

Ответ 23

Возможность хранить UIElement (s) в TextBlock

Я не знаю, насколько полезен (он квалифицируется как скрытый, хотя) это... но он наверняка заставил меня остерегаться, когда я впервые столкнулся с ним

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

Вы можете утверждать, что следующий xaml может быть полезен (например, поместить графику в конец некоторого текста):

<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 отображает следующее:

Hello World

Ответ 24

Отладка анимаций

Общие ошибки

Если вы получите следующую ошибку: не можете анимировать '(0). (1)' на экземпляре неизменяемого объекта. возможно, вы столкнулись с одним из следующих ограничений:

  • Вы анимируете свойство зависимостей без установки локального значения
  • Вы анимируете свойство зависимости, текущее значение которого определено в другой сборке, которая не объединена в словарь ресурсов.
  • Вы анимируете значение, которое в настоящее время поддерживает данные

Ответ 25

Связывание без INotifyPropertyChanged или DependencyProperties

Как обсуждалось здесь, вы можете связать простое свойство объекта CLR без INotifyPropertyChanged, и оно будет работать.

Вот the forumpost, о котором я говорю.

Цитата:

[...] Механизм привязки данных WPF привяжет данные к экземпляру PropertyDescriptor, который обертывает исходное свойство, если исходный объект является простым объектом CLR и не реализует интерфейс INotifyPropertyChanged. И механизм привязки данных попытается подписаться на событие с измененным свойством через метод PropertyDescriptor.AddValueChanged(). И когда элемент данных, привязанный к целевым данным, изменит значения свойств, механизм привязки данных вызовет метод PropertyDescriptor.SetValue() для переноса измененного значения обратно в исходное свойство и одновременно будет вызывать событие ValueChanged для уведомления других подписчиков (в данном случае, другие подписчики будут TextBlocks в ListBox.

И если вы внедряете INotifyPropertyChanged, вы несете полную ответственность за внедрение уведомления об изменении в каждом наборе свойств, которые должны быть привязаны к пользовательскому интерфейсу. В противном случае изменение будет не синхронизировано, как вы ожидали. [...]

Вот еще отличная и подробная статья по этому вопросу.

Примечание это работает только при использовании привязки. Если вы обновите значения из кода, изменение не будет уведомлено. [...]

Реализация INotifyPropertyChanged может быть справедливой частью утомительной разработки. Тем не менее, вам нужно взвесить эту работу против рабочего пространства (памяти и процессора) вашего приложения WPF. Внедрение INPC само по себе позволит сэкономить процессор и память времени выполнения.