使用任意UserControl集合时的ItemsControl DataTemplate

时间:2015-05-04 20:38:02

标签: wpf vb.net xaml

上下文

我正在为我的用户开发一体化虚拟桌面,其中大多数任务需要通过模式对话框输入。一些超级用户可以浏览多种配置对话框,这会导致第二级对话框的出现(第一个模态对话框调用另一个对话框)。根据内部设计方向,每个对话框都放置在半透明的灰色背景上。

为了避免一遍又一遍地编写灰色背景面板,我想我可以使用ItemsControl来堆叠我的对话框。我的概念证明使用 String 的集合创造了奇迹。到目前为止一切都很好。

问题

使用 UserControl 的集合作为 ItemsSource 时,事情变得奇怪。 WPF显示实际的 UserControl 而不是 ItemTemplate 。当集合的项目是UIElements时,感觉就像甚至没有使用模板。

的Xaml

<ItemsControl ItemsSource="{Binding SomeList}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid Background="#AA000000">
                <Label Content="Does it work" />
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

背后的代码

Public ReadOnly Property SomeOtherList As UserControl()
    Get
        Return New UserControl() {New MyControl}
    End Get
End Property

Public ReadOnly Property SomeList As String()
    Get
        Return New String() {"One item"}
    End Get
End Property

实际问题

当ItemsSource项目已经拥有一个时,有没有办法指定模板?更进一步,我们是否可以在保持实际UserControl不变的情况下模拟一个包装器周围的UserControl?

我知道整个事情可能会被使用后面的代码欺骗,但依赖VB或C#不会被忽视代码审查。我们在这里寻找XAML解决方案。

P.S。只要有一种统一的方式来调用任意数量的对话框,我就会接受新的解决方案。

1 个答案:

答案 0 :(得分:1)

经过两天的测试,我很欣赏最初的方法是不可能的,或者至少在我的知识范围内。我提出了一个不错的包装解决方案。

<强>包装

<UserControl x:Class="HolderPopup"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid Background="#AA000000" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
        <Border Style="{StaticResource ResourceKey=borderBase}" />
        <Grid Name="placeHolder" Margin="10" />
    </Grid>
</UserControl>

后面的包装器代码有一个构造函数,您可以将UserControl传递给 placeHolder 的子项,这样可以让您使用它,如下所示:

<强>用法

Private Shared _popup As ObservableCollection(Of UserControl)

Private Shared ReadOnly Property Popup As ObservableCollection(Of UserControl)
    Get
        If _popup Is Nothing Then _popup = New ObservableCollection(Of UserControl)
        Return _popup
    End Get
End Property

Public Shared Sub ModalPush(item As UserControl)
    Popup.Add(New HolderPopup(item))
End Sub

Public Shared Sub ModalPop()
    If Popup.Count > 0 Then Popup.RemoveAt(Popup.Count - 1)
End Sub

'For WPF binding
Public ReadOnly Property PopupRef As ObservableCollection(Of UserControl)
    Get
        Return Main.Popup()
    End Get
End Property

任何事件处理程序,应用程序中的任何位置都可以调用Main.ModalPush,以便在已经存在的位置之上堆叠模态窗口。

虽然这个解决方案尊重约束(统一弹出处理而不会在我的弹出窗口中强制出现一些hackish依赖)我并不完全满意。我觉得它应该可以通过模板化,这将有利于删除这个新的包装类。总而言之,这是另一种选择,但并不完全是我想要的。