我怎样才能制作一个“手风琴小部件”?在 WPF 中?

发布于 2024-08-06 07:52:06 字数 4326 浏览 2 评论 0原文

目标:

我试图在 WPF 中实现类似的目标:

带有多个垂直堆叠扩展器的小部件
(来源:wordpress.org


初步解决方案:

目前,我尝试将 ItemsControl 与由 Expander< 组成的 ItemTemplate 结合使用/代码>。

我希望 ExpanderHeader 部分具有一致的外观,但我希望 ExpanderContent 部分完全灵活。因此,它基本上是一组垂直堆叠的“portlet”,其中每个 portlet 都有一致的标题栏,但内容不同。


到目前为止的代码:

这是我目前所拥有的:

<ItemsControl
    Grid.Row="2"
    Grid.Column="2">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Expander>
                <Expander.HeaderTemplate>
                    <DataTemplate>
                        <StackPanel
                            Orientation="Horizontal">
                            <TextBlock
                                FontSize="14"
                                FontWeight="Bold"
                                Text="Title_Of_Expander_Goes_Here" />
                            <TextBlock
                                Margin="10,0,0,0"
                                FontWeight="Bold"
                                FontSize="18"
                                Text="*" />
                        </StackPanel>
                    </DataTemplate>
                </Expander.HeaderTemplate>
                <Expander.Template>
                    <ControlTemplate
                        TargetType="Expander">
                        <Border
                            BorderThickness="1">
                            <ContentPresenter />
                        </Border>
                    </ControlTemplate>
                </Expander.Template>
            </Expander>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.Items>
        <StackPanel>
            <TextBlock
                FontSize="14"
                FontWeight="Bold"
                Text="Users:" />
            <wt:DataGrid
                Margin="0,1,0,0"
                AutoGenerateColumns="False"
                CanUserAddRows="True"
                CanUserDeleteRows="True"
                ItemsSource="{Binding Source={StaticResource Main_SystemUsers}, XPath=//Users/*}">
                <wt:DataGrid.Columns>
                    <wt:DataGridTextColumn
                        Header="User Name"
                        Binding="{Binding XPath=@UserName}" />
                    <wt:DataGridComboBoxColumn
                        Header="Role"
                        ItemsSource="{Binding Source={StaticResource Main_UserRoles}, XPath=//Roles/*}"
                        SelectedValueBinding="{Binding XPath=@Role}" />
                </wt:DataGrid.Columns>
            </wt:DataGrid>
            <StackPanel
                Margin="0,10,0,0"
                Orientation="Horizontal">
                <Button
                    Content="Add New User..." />
                <Button
                    Margin="10,0,0,0"
                    Content="Delete User..." />
            </StackPanel>
        </StackPanel>
    </ItemsControl.Items>
</ItemsControl>

讨论:

当我运行此代码时,唯一显示的是DataGrid用户及其下方的按钮(“添加新用户”和“删除用户”)。没有 Expander 或标题栏。另外,即使我确实看到了一个,我也不知道如何为标题栏上显示的标题设置 Binding。如果我使用 ItemsSource,我知道如何进行绑定,但我想以声明方式设置我的项目。

问题:

我应该如何解决这个问题?我正在寻找现有的解决方案或干净的解决方案。

编辑:

我最终做的是用 StackPanel 替换 ItemsControl 并为我的扩展器编写一个样式。事实证明这要简单得多,而且 ItemsControl 确实没有任何好处,因为无论如何我都需要为每个项目声明自定义内容。剩下的一个问题是如何为每个扩展器实现自定义标题。这就是 @Thomas Levesque 建议使用 TemplateBinding 的地方。我所要做的就是将我的标头模板中的 Text="Title_Of_Expander_Goes_Here" 替换为 >Text="{TemplateBinding 内容}"

The goal:

I'm trying to achieve something like this in WPF:

Widget with several vertically stacked expanders
(source: wordpress.org)


An initial solution:

At the moment, I'm trying to use an ItemsControl with an ItemTemplate composed of an Expander.

I want a consistent look for the Header portion of the Expander, but I want the Content portion of the Expander to be completely flexible. So, it's basically a set of "portlets" stacked vertically, where each portlet has a consistent title bar but different content.


The code so far:

This is what I have at the moment:

<ItemsControl
    Grid.Row="2"
    Grid.Column="2">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Expander>
                <Expander.HeaderTemplate>
                    <DataTemplate>
                        <StackPanel
                            Orientation="Horizontal">
                            <TextBlock
                                FontSize="14"
                                FontWeight="Bold"
                                Text="Title_Of_Expander_Goes_Here" />
                            <TextBlock
                                Margin="10,0,0,0"
                                FontWeight="Bold"
                                FontSize="18"
                                Text="*" />
                        </StackPanel>
                    </DataTemplate>
                </Expander.HeaderTemplate>
                <Expander.Template>
                    <ControlTemplate
                        TargetType="Expander">
                        <Border
                            BorderThickness="1">
                            <ContentPresenter />
                        </Border>
                    </ControlTemplate>
                </Expander.Template>
            </Expander>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.Items>
        <StackPanel>
            <TextBlock
                FontSize="14"
                FontWeight="Bold"
                Text="Users:" />
            <wt:DataGrid
                Margin="0,1,0,0"
                AutoGenerateColumns="False"
                CanUserAddRows="True"
                CanUserDeleteRows="True"
                ItemsSource="{Binding Source={StaticResource Main_SystemUsers}, XPath=//Users/*}">
                <wt:DataGrid.Columns>
                    <wt:DataGridTextColumn
                        Header="User Name"
                        Binding="{Binding XPath=@UserName}" />
                    <wt:DataGridComboBoxColumn
                        Header="Role"
                        ItemsSource="{Binding Source={StaticResource Main_UserRoles}, XPath=//Roles/*}"
                        SelectedValueBinding="{Binding XPath=@Role}" />
                </wt:DataGrid.Columns>
            </wt:DataGrid>
            <StackPanel
                Margin="0,10,0,0"
                Orientation="Horizontal">
                <Button
                    Content="Add New User..." />
                <Button
                    Margin="10,0,0,0"
                    Content="Delete User..." />
            </StackPanel>
        </StackPanel>
    </ItemsControl.Items>
</ItemsControl>

Discussion:

The only thing that shows up when I run this is the DataGrid of users and the buttons ("Add New User" and "Delete User") below it. There is no Expander or title bar. Also, even if I did see one, I'm not sure how to set up a Binding for the title that appears on the title bar. I know how to do bindings if I use ItemsSource, but I wanted to set my items declaratively.

The question:

How should I go about this? I'm looking for either a fix for what I have now or a clean-sheet solution.

Edit:

What I ended up doing was replacing the ItemsControl with a StackPanel and just writing a style for my expanders. This proved to be much simpler, and there really was no benefit to the ItemsControl since I needed to declare custom content for each item anyway. The one issue remaining was how to achieve a custom title for each expander. That's where @Thomas Levesque's suggestion to use TemplateBinding came in. All I had to do was replace Text="Title_Of_Expander_Goes_Here" in my header's template (see code above) with Text="{TemplateBinding Content}".

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

对风讲故事 2024-08-13 07:52:06

您没有看到 Expander,因为您重新定义了它的模板。这个应该效果更好:

        ...
        <Expander.Template>
          <ControlTemplate
              TargetType="Expander">
              <Border
                  BorderThickness="1">
                  <Expander Content="{TemplateBinding Content}" Header="{TemplateBinding Header}"/>
              </Border>
          </ControlTemplate>
        </Expander.Template>
        ...

You're not seeing the Expander because you redefined its template. This one should work better :

        ...
        <Expander.Template>
          <ControlTemplate
              TargetType="Expander">
              <Border
                  BorderThickness="1">
                  <Expander Content="{TemplateBinding Content}" Header="{TemplateBinding Header}"/>
              </Border>
          </ControlTemplate>
        </Expander.Template>
        ...
你没皮卡萌 2024-08-13 07:52:06

我个人认为 TreeView 控件将为您提供更好的工作基础,特别是如果您使用 Expression Blend 作为为项目创建新/空白模板的基础。查看默认模板非常有启发性,可以让您进行更细粒度的控制,并更好地理解和洞察默认情况下的工作方式。然后你就可以带着它们进城了。看起来您正在使用分层数据,而 TreeView 本质上非常适合处理此类数据。

Personally I think a TreeView control would give you a much better base to work from, especially if you're using Expression Blend as a basis to create new/blank Templates from for items. Seeing the default Templates is extremely enlightening and gives you much more fine-grained control and better understanding and insight into how things work by default. Then you can go to town on them. It also looks like you're working with Hierchical Data and TreeViews inherently lend themselves well to working with such data.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文