使用Caliburn.Micro在嵌套ListBox中绑定SelectedItem

时间:2014-01-13 11:08:31

标签: c# wpf data-binding listbox caliburn.micro

我正在尝试使用Caliburn.Micro来绑定嵌套ListBox的视图模型但我被卡住了。 我有一个列表工作区,分为两个部分,一组包含该工作区不同部分中的项目的组列表我想显示一个组或组中项目的详细信息,具体取决于SelectedItem的内容。我是Caliburn.Micro的新手并查看了文档和样本,但不知道如何连接点。具体来说,我试图在Caliburn.Micro.HelloScreens样本之后对此进行建模。我到目前为止的代码:

ViewModel:

public class AnalyzerGroupWorkspaceViewModel : Conductor<AnalyzerGroupWorkspaceViewModel>, IWorkspace
{
    private Selected selected = Selected.AnalyzerGroup;

    private const string name = "Analyzers";

    public AnalyzerGroupWorkspaceViewModel(
        IMappingEngine fromMapper,
        IRepository<Model.AnalyzerGroup> analyzerGroups)
    {
        AnalyzerGroups = new ObservableCollection<IAnalyzerGroupViewModel>(analyzerGroups.GetAll().Select(fromMapper.Map<Model.AnalyzerGroup,AnalyzerGroupViewModel>));
    }

    public ObservableCollection<IAnalyzerGroupViewModel> AnalyzerGroups { get; private set; }

    public string Name { get { return name; } }

    public Selected Selected
    {
        get { return selected; }
        set
        {
            if (value == selected) return;
            selected = value;
            NotifyOfPropertyChange(() => Selected);
        }
    }

    private IConductor Conductor { get { return (IConductor) Parent; } }

    public void Show()
    {
        var haveActive = Parent as IHaveActiveItem;
        if (haveActive != null && haveActive.ActiveItem == this)
        {
            DisplayName = name;
            Selected = Selected.AnalyzerGroup;
        }
        else
        {
            Conductor.ActivateItem(this);
        }
    }
}

观点:

<UserControl x:Class="Philips.HHDx.SSW.AnalyzerGroup.AnalyzerGroupWorkspaceView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:cal="http://www.caliburnproject.org">
    <DockPanel>
        <GroupBox Header="AnalyzerGroups" DockPanel.Dock="Top">
            <ListBox x:Name="AnalyzerGroups">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="{Binding Name}" />
                            <ListBox x:Name="Analyzers">
                                <ListBox.ItemTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding Id }"></TextBlock>
                                    </DataTemplate>
                                </ListBox.ItemTemplate>
                            </ListBox>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </GroupBox>
    <GroupBox Header="Details">
        <ContentControl cal:View.Context="{Binding Selected, Mode=TwoWay}"
                        cal:View.Model="{Binding}"
                        VerticalContentAlignment="Stretch"
                        HorizontalContentAlignment="Stretch"/>
    </GroupBox>
    </DockPanel>
</UserControl>

接下来,我有两个显示组或项目详细信息的UserControl。 我的具体问题是如何使用两个SelectedItem的{​​{1}}属性修改ListBoxes属性,以便在显示Selected详细信息和AnalyzerGroup之间切换细节?

2 个答案:

答案 0 :(得分:1)

我找到了上述问题的解决方案,该解决方案由四部分组成:

  • 向'child'ViewModels
  • 添加IsSelected属性(通知更改)
  • IsSelected的{​​{1}}属性绑定到相应ViewModels的ListBox.ItemContainerStyle属性
  • 将Caliburn.Micro IsSelected附加到'外部'Message并使用ListBox参数
  • 在绑定到整个UserControl的ViewModel中,实现与$eventArgs对应的方法,并使用Message的{​​{1}}属性设置AddedItems属性设置{上一个eventArgsSelectedViewModel
  • 的{1}}属性

然后代码变为:

ViewModel:

IsSelected

观点:

SelectedViewModel

答案 1 :(得分:0)

你的具体问题的答案是肯定的,你可以。

在UserControl的ViewModel上。您创建一个属性,该属性是两个详细信息之一的ViewModel。

public interface IAnalyzerViewModel
{

}

接下来,为AnalyzerAnalyzerGroup视图的视图创建两个ViewModel。

public class AnalyzerGroupViewModel : IAnalyzerViewModel 
{

}

public class AnalyzerViewModel : IAnalyzerViewModel
{

}

接下来,在UserControl的ViewModel中创建一个实现INPCPropertyChangedBase Caliburn Micro的属性。

public class MainViewModel :
{
  private IAnalyzerViewModel _analyzerViewModel;
  public IAnalyzerViewModel SelectedViewModel { get { return _analyzerViewModel; } set { _analyzerViewModel = value; OnPropertyChanged(() => SelectedViewModel); }

  //Hook up the selected item changed event of your listbox and set the appropriate ViewModel to show, so if you either want to show the AnalyzerGroup or AnalyzerView.
}

最后,只需将MainView更新为

即可
<ContentControl x:Name="SelectedViewModel"
                VerticalContentAlignment="Stretch"
                HorizontalContentAlignment="Stretch"/>

Caliburn将连接相应的绑定和东西,并为相关的ViewModel提取View,并且只要名称匹配,Name约定部分将自动将其映射到其datacontext的任何公共属性。