问题
Given that I have the following widget (and a view attached to it):
public class MyWidgetViewModel : Screen {}
I can use and display it easily in an another view. The view model "hosting" the widget looks like the following:
public class WidgetWorkspaceViewModel : Screen
{
private Screen myWidget = new MyWidgetViewModel();
public Screen MyWidget
{
get { return myWidget; }
set { myWidget = value; }
}
}
And the control is shown on WidgetWorkspaceView like this:
<ContentControl x:Name="OneWidget"/>
This all works nicely. But now I would like to change it so that the WidgetWorkspaceViewModel would contain a collection of Widgets and the WidgetWorkspaceView should show them one after another. And I'm having some problems getting this to work.
The view model is supposed to look like this:
private List<Screen> widgets;
public List<Screen> Widgets
{
get { return widgets; }
set { widgets = value; NotifyOfPropertyChange(() => Widgets); }
}
This part of the code is OK, because I've binded the Widgets to a combobox and the combobox shows a list of controls correctly. But I'm having problems "hosting" the widgets on the view. This is the XAML I've tried to use in the WidgetWorkspaceView but without a success:
<ListBox x:Name="Widgets">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<ContentControl Width="100" Height="100" DataContext="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Based on the breakpoints, the databinding part is working OK but I'm not getting the widgets drawn.
Any ideas how to solve this? I'm using Caliburn.Micro to help out with the bindings.
回答1:
I think the problem is that Caliburn.Micro will automatically define the ItemTemplate for an ItemsControl, which you'll be overriding, so you'll either need to remove that from your ListBox, or if you want to define it, then use the View
attached property to set the model.
<ListBox.ItemTemplate>
<DataTemplate>
<ContentControl Width="100" Height="100" cal:View.Model="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
Note that you could also use a Conductor
such as Conductor<IScreen>.Collection.OneActive
or Conductor<IScreen>.Collection.AllActive
as your WidgetWorkspaceViewModel
type rather than maintain your own Screen
list. These conductors have an Items
collection, and support screen life cycle.
来源:https://stackoverflow.com/questions/5228873/binding-listbox-to-a-collection-of-screens-widgets