Bind a generic list to a listbox and also use a datatemplate
I'm trying to implement something quite simple but I'm on my first steps in WPF and I'm having some problems. I have a class called Component which has a property called Vertices. Vertices is a generic List of type Point. What I want is to bind the vertices property to a listbox. This is easy by using this code in my XAML in the listbox declaration:
ItemsSource="{Binding Path=Component.Vertices, Mode=OneWay, Converter={StaticResource verticesconverter},UpdateSourceTrigger=PropertyChanged}"
The tricky part is when I try to create a datatemplate for the listbox. I want each row of the listbox to display a textbox with the values of the Vertex (Point.X, Point.Y) and a button to allow me to delete the item. Could you help me on the datatemplate definition. The code below doesn't work to bind the X,Y values into two separate textboxes. Could you开发者_JAVA百科 point me on the mistake and why nothing is displayed in the textboxes?
<ListBox ItemsSource="{Binding Path=Component.Vertices, Mode=OneWay,UpdateSourceTrigger=PropertyChanged}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBox Text="{Binding X}" MinWidth="35" MaxWidth="35"/>
<TextBox Text="{Binding Y}" MinWidth="35" MaxWidth="35"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
/ListBox>
Something like this:
<ListBox ... Grid.IsSharedSizeScope="True">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="A"/>
<ColumnDefinition SharedSizeGroup="B"/>
<ColumnDefinition SharedSizeGroup="C"/>
</Grid.ColumnDefinitions>
<Grid.Children>
<TextBlock Grid.Column="0" Text="{Binding X}" Margin="5"/>
<TextBlock Grid.Column="1" Text="{Binding Y}" Margin="5"/>
<Button Grid.Column="2" Tag="{Binding}" Margin="5" Click="Button_Click" Content="Remove"/>
</Grid.Children>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Event handler:
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
Button senderB = (Button)sender;
Point pt = (Point)senderB.Tag;
Collection.Remove(pt);
}
Note: Your list in the GUI will not get updated unless your bound collection implements INotifyCollectionChanged
(Standard-implementation you can use: ObservableCollection<T>
)
Edit: Common binding-fail causes:
1. Bound source is not a public property -> make it one
2. Binding path is not absolute and there is no DataContext to start from
-> Set DataContext of your window in the constructor to itself (this
) or...
-> Set ElementName in the Binding to the name of your window if that is where your property is
Edit2: If your collection consists of Vertices and if your Vertex
class contains a point with the property-name Point
you need to change the bindings to {Binding Point.X}
and {Binding Point.Y}
, post more code next time please.
精彩评论