WPF Strange problem with dynamically binding items to a new ListBox
here's the code. All it does is, it creates a new ListBox control inside a StackPanel and adds to it a new Item. The problem is described at the bottom of the page.
MyWindow.xaml
<Window.Resources>
<DataTemplate x:Key="itemsTemplate">
<Border Width="200" Height="50" >
<ListBox ItemsSource="{Binding Title}" />
</Border>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ItemsControl Grid.Column="1"
Grid.Row="0"
ItemsSource="{Binding ElementName=mainWindow, Path=DataItems}"
ItemTemplate="{StaticResource itemsTemplate}">
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
MyWindow.xaml.cs
private ObservableCollection<MyDataItem> dataItems;
public ObservableCollection<MyDataItem> DataI开发者_开发百科tems
{
get { return dataItems; }
}
public Window1()
{
dataItems = new ObservableCollection<MyDataItem>();
InitializeComponent();
}
MyDataItem.cs
public class MyDataItem : DependencyObject
{
public string Title
{
get
{
return (string)GetValue(TitleProperty);
}
set
{
SetValue(TitleProperty, value);
}
}
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string),
typeof(MyDataItem), new UIPropertyMetadata(""));
public MyDataItem(string title)
{
Title = title;
}
}
Add a new Listbox with item
void addNewItem_Click(object sender, RoutedEventArgs e)
{
MyDataItem item = new MyDataItem("12");
dataItems.Add(item);
e.Handled = true;
}
after that action, I see that new ListBox control, but all its item's characters are treated as a separate items as You can see @ the picture. Why ?
[ EDIT ]
solved, I had to change from string to List everywhere in that class:
public class MyDataItem : DependencyObject
{
public List<string> Title
{
get
{
return (List<string>)GetValue(TitleProperty);
}
set
{
SetValue(TitleProperty, value);
}
}
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string),
typeof(MyDataItem),
new UIPropertyMetadata(new List<string>()));
public MyDataItem(List<string> title)
{
Title = title;
}
}
Because you are giving data source as string.. it is converting that string to collection (character array) since itemssource property will always be collection..
if you still want to create a list box in data template with single item (in you case it is Title).. then try this..
Change you title property to List and while creating your title create a list which contains one string . so item source will be list and since itemssource contains one string it will create only one item.
That's correct, because you declared to instantiate a listbox for each item. Since an item is exposing a string (thus an array of characters), the listbox shows correctly one char for every row.
Why do you insert an ItemsControl (the listbox) inside another ItemsControl?
Cheers
精彩评论