확장 가능한 피아노 키보드를 만들기 위해 첨부 된 속성을 사용하여 ItemsControl로 WPF Grid를 사용하려고합니다. 키보드의 각 키는 앞뒤의 내용에 따라 1에서 3 열까지 확장 될 수 있으며 선명한 경우 1 행, 자연의 경우 2 행을 차지합니다. Grid의 Column Count와 Row Count를 동적으로 설정할 수있는 2 개의 속성이 이미 있습니다. (각 열/행의 너비/높이 설정을 지원하기 위해 조정해야하지만).ItemTemplate 및 ItemsSource에 대한 부착 가능한 속성을 구현하는 방법
지금 구현해야 할 것은 ItemsSource
(Keys)과 ItemTemplate
(PianoKeyView)의 두 가지 부착 가능 속성입니다. ItemsControl
은 ItemsPanel
에 대해서만 UniformGrid
을 그리드로 지원하며 특정 항목/행에 특정 항목을 지정하지 않으므로 Grid 컨트롤에서 사용해야합니다. 내 피아노 키보드는 옥타브 당 17 개의 열을 필요로하지만 ItemsControl은 12 개의 키만 전달되므로 UniformGrid
에 12 개의 열만 만듭니다. 필자는 각 필수 열의 색인이 포함 된 1 옥타브 피아노 키보드의 이미지를 포함 시켰습니다. 그것이 현재 내가 GridExtensions.ItemsSource
및 GridExtensions.ItemTemplate
에 대한 구현을 잃었 약자로
이 키보드에 대한 내 코드입니다. GridExtensions
은 부착 가능한 속성을 포함하는 정적 클래스입니다.
그리고이 GridExtensions의 ItemTemplate을 부착 속성에 대한 ItemTemplateChanged 처리기에 대한 코드는
<UserControl x:Class="SphynxAlluro.Music.Wpf.PianoKeyboard.View.PianoKeyboardView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:converters="http://schemas.sphynxalluro.com/converters"
xmlns:local="clr-namespace:SphynxAlluro.Music.Wpf.PianoKeyboard.View"
xmlns:prism="http://www.codeplex.com/prism"
xmlns:sphynxAlluroControls="http://schemas.sphynxalluro.com/controls"
xmlns:wpfBindingExtensions="http://schemas.sphynxalluro.com/bindingExtensions"
mc:Ignorable="d"
d:DesignHeight="200" d:DesignWidth="600">
<UserControl.Resources>
<converters:KeysToColumnsCountConverter x:Key="keysToColumnsCountConverter"/>
<converters:KeysToRowsCountConverter x:Key="keysToRowsCountConverter"/>
<converters:IsSharpToRowSpanConverter x:Key="isSharpToRowSpanConverter"/>
<converters:KeysCollectionAndKeyToColumnIndexConverter x:Key="keysCollectionAndKeyToColumnIndexConverter"/>
<converters:KeysCollectionAndKeyToColumnSpanConverter x:Key="keysCollectionAndKeyToColumnSpanConverter"/>
</UserControl.Resources>
<Grid wpfBindingExtensions:GridExtensions.ItemsSource="{Binding Keys}"
wpfBindingExtensions:GridExtensions.ItemsOrientation="Horizontal"
wpfBindingExtensions:GridExtensions.ColumnCount="{Binding Keys, Converter={StaticResource keysToColumnsCountConverter}}"
wpfBindingExtensions:GridExtensions.RowCount="{Binding Keys, Converter={StaticResource keysToRowsCountConverter}}">
<wpfBindingExtensions:GridExtensions.ItemTemplate>
<DataTemplate>
<local:PianoKeyView Grid.RowSpan="{Binding Note.IsSharp, Mode=OneTime, Converter={StaticResource isSharpToRowSpanConverter}}"
DataContext="{Binding}">
<Grid.Column>
<MultiBinding Converter="{StaticResource keysCollectionAndKeyToColumnIndexConverter}" Mode="OneTime">
<Binding RelativeSource="{RelativeSource AncestorType=ItemsControl}" Path="Items"/>
<Binding/>
</MultiBinding>
</Grid.Column>
<Grid.ColumnSpan>
<MultiBinding Converter="{StaticResource keysCollectionAndKeyToColumnSpanConverter}" Mode="OneTime">
<Binding RelativeSource="{RelativeSource AncestorType=ItemsControl}" Path="Items"/>
<Binding/>
</MultiBinding>
</Grid.ColumnSpan>
</local:PianoKeyView>
</DataTemplate>
</wpfBindingExtensions:GridExtensions.ItemTemplate>
</Grid>
은 컴파일되지 않는 선 위의 두 수행 할 작업을 확인합니다. 내가 직접
Grid
의
ItemsPanel
와 함께
ItemsControl
을 달성 할 수있는
Grid
달성하기 위해 노력했다
private static void ItemTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var itemTemplate = (DataTemplate)e.NewValue;
var itemsSource = GetItemsSource(d);
var itemsSourceCount = itemsSource.Count();
var itemsOrientation = GetItemsOrientation(d);
var gridChildren = ((Grid)d).Children;
gridChildren.Clear();
switch (itemsOrientation)
{
case Orientation.Horizontal:
foreach (var item in itemsSource)
{
var itemFactory = new FrameworkElementFactory(item.GetType());
//TODO: Find out where the ContentProperty for Grid is.
itemFactory.SetValue(d.ContentProperty, item);
itemTemplate.VisualTree = itemFactory;
//TODO: Find out how to add the applied itemTemplate.
gridChildren.Add(itemTemplate);
}
break;
case Orientation.Vertical:
break;
default:
throw new EnumValueNotSupportedException(itemsOrientation, nameof(itemsOrientation).ToPascalCase());
}
}
5 변환기 및 4 DP 부착? 더 복잡한보기 대신 복잡한보기를 사용하면 ItemsControl의 바인딩에 더 편리한 양식을 데이터에 갖도록보기 모델을 단순화해야합니다. – ASh
다른 옵션은 ItemsPanelTemplate에서 가로 StackPanel을 사용하고 음수 여백 및 Panel.ZIndex로 재생하는 것입니다. 스타일/바인딩을 통해/인접하지 않은 흰색 키를 확장하고 검정 키의 "아래"를 만나는 것은 무엇이든합니다. –
@Ed Plunkett @ASS ItemsControl을 사용하고 싶지만 12 개 항목에 대해 17 개의 열을 생성하려면 어떻게해야합니까? 나는 원래 이것을'ItemsControl'으로 가지고 있었지만'PianoKey'의'Grid.Column'과'Grid.Row' 속성은'UniformGrid'에서 작동하지 않았습니다. 그리고'Grid'가 'ItemsPanelTemplate'은 컬럼을 생성하지 않았습니다. – Sphynx