问题
I want to have a graphical part in my UserControl which will display Lines based on a collection (and update coords during runtime and also add/remove lines during runtime based on the collection).
Lets assume I have a class called Class1:
public class Class1 : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
}
private int _x1 = 0;
public int X1
{
get { return _x1; }
set
{
_x1 = value;
OnPropertyChanged(new PropertyChangedEventArgs("X1"));
}
}
}
And an ObservableCollection in my UserControl:
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
}
private ObservableCollection<Class1> _classes = new ObservableCollection<Class1>();
public ObservableCollection<Class1> Classes
{
get { return _classes; }
}
If I knew the amount of Lines I could create the number of lines in my UserControl like this:
XAML:
<Grid DataContext="{Binding ElementName=LayoutRoot}">
<Line X1="{Binding Items[0].X1}" X2="100" Y1="50" Y2="100" Stroke="Red" StrokeThickness="4"/>
<Line X1="{Binding Items[1].X1}" ... />
...
</Grid>
How should I proceed please?
Thanks for any efforts
回答1:
You could use an ItemsControl
and create a DataTemplate
for the Class1
object and bind your ObservableCollection
to the ItemsControl
.
It may also be a good idea to use Canvas
as the ItemsPanelTemplate
if you want to draw lines all over the place
Here is a quick example:
Xaml:
<Grid DataContext="{Binding ElementName=UI}">
<ItemsControl ItemsSource="{Binding Classes}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:Class1}">
<Line Stroke="Black" StrokeThickness="2" Fill="Black" X1="{Binding X1}" X2="{Binding X2}" Y1="{Binding Y1}" Y2="{Binding Y2}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
Code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Random ran = new Random();
for (int i = 0; i < 10; i++)
{
Classes.Add(new Class1 { X1 = ran.Next(0,100), Y1 = ran.Next(0,100), X2 = ran.Next(0,100), Y2 = ran.Next(0,100) });
}
}
private ObservableCollection<Class1> _classes = new ObservableCollection<Class1>();
public ObservableCollection<Class1> Classes
{
get { return _classes; }
}
}
Result:

回答2:
You could use an ItemsControl as Container to display your lines.
<ItemsControl DataContext="{Binding ElementName=LayoutRoot}"
ItemsSource={Binding}>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Line X1="{Binding Items[0].X1}" X2="100" Y1="50" Y2="100" Stroke="Red" StrokeThickness="4"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
来源:https://stackoverflow.com/questions/15426460/bind-an-observablecollection-to-lines