INTRODUCTION
So, guys, I am making an application to show musical notes, for example :
PROBLEM EXPLANATION
Okay, for "drawing that image", it have to broken down into some parts (because it's impossible to given "preformatted image, since musical notation is really various), like below.
THE CLASSES
Let's say "Red" is a "NoteHead", "Blue" is a "NoteBeam" and "Yellow" is a "NotePole". Given those, these are my mockup classes :
public class MainWindowVM : ViewModelBase
{
public ObservableCollection<Mockup> MockupCollection { get; set; }
}
public abstract class Mockup
{
public Point TopLeftCanvasCoordinate { get; set; }
}
public class NoteHead : Mockup
{
//A note can be black or transparent filled
public SolidColorBrush NoteFill { get; set; }
}
public class NoteBeam : Mockup
{
public Point LineStartCoordinate { get; set; }
public Point LineEndCoordinate { get; set; }
public double LineThickness { get; set; }
}
public class NotePole : Mockup
{
public Point LineStartCoordinate { get; set; }
public Point LineEndCoordinate { get; set; }
public double LineThickness { get; set; }
}
Let's assume the Point class above have both X and Y are double, not int.
THE XAML
NoteHead always Binded to an Ellipse
<Ellipse Width="10" Height="10" Fill="{Binding NoteFill}" Stroke="Black" StrokeThickness="1"> <Ellipse.RenderTransform> <SkewTransform AngleX="-15" CenterX="5" CenterY="5"/> </Ellipse.RenderTransform> </Ellipse>
NotePole and NoteBeam always Binded to a Line
<Line X1="{Binding LineStartCoordinate.X}" Y1="{Binding LineStartCoordinate.Y}" X2="{Binding LineEndCoordinate.X}" Y2="{Binding LineEndCoordinate.Y}" Stroke="Black" StrokeThickness="{Binding LineThickness}"/>
Assume all
Canvas.Top
andCanvas.Left
above put in theItemsControl
section
So, the reason why I want to use ItemsControl
is because I don't know how many Mockup
s will be drawn in the canvas. It's totally varies.
1 ItemsControl
can contain more than 1 Musical Notation. (It doesn't have limitation afterall). As long as the collection it binded to have 100 items (mixed along between Head, Pole, and Beam), it will draw them all to the Canvas. (Btw, if you understand music, then 1 canvas contains of 1 measure / bar, otherwise it doesn't really matter to the solution)
THE QUESTIONS
- How to properly build the
ItemsControl
to represent such structure? *The problem, I think lies on the shape variety, eitherEllipse
orLine
. Because, as far as I know, aDataTemplate
can only contains 1UIElement
. - How to properly "attach" Canvas properties to the control in
ItemsControl
? I read this similar SO post, but when I tried it out, it doesn't work. Please include the setting for Canvas properties in your solution.
ADDITIONAL NOTE
Maybe the solution I aimed will look something like this. It's possibly not the correct one I know. It's just to give you a more concrete view on what the solutin should look like.
<ItemsControl Grid.Column="0" Grid.Row="0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left"
Value="{Binding Path=TopLeftCanvasCoordinate.X}" />
<Setter Property="Canvas.Top"
Value="{Binding Path=TopLeftCanvasCoordinate.Y}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<!--THIS SHOULD BE FILLED WITH MOCKUP (HEAD / POLE / BEAM)-->
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Thanks for reading this long post.