Скрытые функции WPF и XAML?
Здесь представлено большое количество скрытых функций для разных языков. Теперь мне интересно узнать некоторые скрытые возможности XAML и WPF?
Одно, которое я нашел, - это событие щелчка заголовка ListView
<ListView x:Name='lv'
Height="150"
GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler">
Свойство GridViewColumnHeader.Click не указано.
Некоторые из важных функций:
См. также:
Ответы
Ответ 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.
Ответ 13
Общий размер сетки (вот хороший пример). Короче говоря, вы можете иметь столбцы сетки и размеры строк, даже в разных сетках. Это будет бесценно для всех людей, которые используют DataGrids, без необходимости редактировать данные на месте.
Ответ 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 само по себе позволит сэкономить процессор и память времени выполнения.