of legends *відео
Свистоперділки на WPF.
Creating a "League of Legends" Inspired Play Button in WPF
of legends *відео
Свистоперділки на WPF.
Creating a "League of Legends" Inspired Play Button in WPF
Цікаво, що відображення тіні під випадаючим списком в ComboBox залежить від значення властивості HasDropShadow елементу керування Popup який є частиною ComboBox. А значення HasDropShadow залежить від SystemParameters.DropShadow та значення AllowsTransparency конкретного обʼєкту класу Popup. SystemParameters.DropShadow використовує значення SPI_GETDROPSHADOW яке повертає функція SystemParametersInfoA з User32.lib і відображає загальносистемне налаштування. Якщо властивості AllowsTransparency здадати значення False, то тіні не буде.
private static object CoerceHasDropShadow(DependencyObject d, object value)
{
return BooleanBoxes.Box(SystemParameters.DropShadow && ((Popup)d).AllowsTransparency);
}
Початкове значеня властивості Color дорівнює Transparent (Colors.Transparent — Gets the system-defined color that has an ARGB value of #00FFFFFF) а вже в стилях ComboBox, якщо значення HasDropShadow = True, змінюється на #71000000 (принаймні для теми Aero). Також змінюється й Margin, бо інакше тінь перекривається випадаючим списоком.
<ControlTemplate.Triggers>
<Trigger Property="HasDropShadow" SourceName="PART_Popup" Value="True">
<Setter Property="Margin" TargetName="Shdw" Value="0,0,5,5"/>
<Setter Property="Color" TargetName="Shdw" Value="#71000000"/>
</Trigger>
За тінь відповідає клас SystemDropShadowChrome (Creates a theme specific look for drop shadow effects.) який ще й залежить від теми оформлення. Якщо в ComboBox немає елементів (HasItems = False), то висота випадаючого списку встановлюється в 95 одиниць. Найбільш можлива висота випадаючого списку обмежується властисвістю MaxDropDownHeight (MaxDropDownHeight = SystemParameters.PrimaryScreenHeight / 3).
Шаблон ComboBox складється з Grid з двома стовпцями. Ширина першого стовпчика є пропорційною (Width="*"), а от друга колонка вже цікавіша тому що для неї задана мінімальна ширина яка відповідає SystemParameters.VerticalScrollBarWidthKey, а сама ширина дорівнє 0. В Grid поміщено спершу ToggleButton розтягнутий на дві колонки (Grid.ColumnSpan="2") і потім ContentPresenter на якому відображається вибраний елемент списку. Обоє розміщені в першій колонці. Мабуть це зроблено для того щоб ContentPresenter відмальовувався над ToggleButton.
Витріщаючись на код ComboBox (написано на Visual C#) натрапив на метод OnKeyDown який перевизначає однойменний метод бактьківского класу і викликає інший метод — KeyDownHandler. Так от, хто не знав і не розумів чому воно не відкривається, коли натискаєш Enter, елемент керування ComboBox відкривається по F4 а Enter його тільки закриває.
Елементи меню поміщені в ListView (через ListView.ItemTemplate) відкриваються за межами вікна з лівого боку екрана. Якщо почати швидко-швидко клацати по по елементам ListView, то Menu таки відкриється там де потрібно. Ще воно висне і їсть багато ЦП. Веде воно себе так через прив'язки висоти і ширини першого елементу MenuItem в Menu до висоти і ширини Menu.
<Menu DataContext="{Binding ElementName=mw, Path=DataContext}">
<MenuItem Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Menu}, Path=ActualWidth}" Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Menu}, Path=ActualHeight}">