【问题标题】:WPF - Databind to a StackPanel using DataTemplatesWPF - 使用 DataTemplates 将数据绑定到 StackPanel
【发布时间】:2010-11-12 05:37:41
【问题描述】:

我修改了我的问题,因为它在尝试时改变了焦点。 我将问题缩小到以下...

我尝试将 TreeView 的选定项绑定到 StackPanel(或其他可以容纳用户控件的容器)。然后,此容器将显示一个 UserControl,具体取决于所选项目的类型。

这是 StackPanel 的 xaml(treeview 和 stackpanel 都在同一个窗口中 ==> 不同的网格列)

<StackPanel Grid.Column="2" MinWidth="500" DataContext="{Binding ElementName=myTree, Path=SelectedItem, Mode=OneWay}">
    <StackPanel.Resources>
        <DataTemplate DataType="{x:Type mvTypes:MyTypeA}">
            <controls:UserControlA DataContext="{Binding}" />
        </DataTemplate>
        <DataTemplate DataType="{x:Type mvTypes:MyTypeB}">
            <controls:UserControlB DataContext="{Binding}" />
        </DataTemplate>
    </StackPanel.Resources>
</StackPanel>

当我将用户控件直接放在堆栈面板下(而不是在资源中)时,它会将所选对象显示为数据上下文。 同样,如果我在其中放置一个 TextBox,它将显示所选项目的正确类型。

<TextBox Name="textBox1" Text="{Binding}" />

出于某种原因,将其放在 DataTemplate 中(即使没有设置 DataType)也不会显示任何内容。

任何建议。我在想也许 StackPanel 不是正确的控件,尽管我似乎找不到其他看起来适合像这样的容器的控件。

提前致谢。

【问题讨论】:

    标签: wpf data-binding datatemplate


    【解决方案1】:

    虽然您在第二个自定义控件上设置了 Binding,但您是否设置了 DataContext,因为绑定是信息的路由,而 DataContext 是它应用此绑定信息的信息。

    安德鲁

    【讨论】:

    • 是的,datacontext 是这样在自定义控件中设置的...(当然非常简化) ModelObject c = repo.GetByID(3295123); ViewModelTree vmt = new ViewModelTree(c); base.DataContext = vmt;难道是我只绑定到用户控件的 DataContext,而不是窗口,因此对窗口中的其他控件不可见?
    【解决方案2】:

    您可以创建一个 UserControl 来在右侧显示 TreeView 和选择信息,所有这些都合二为一。它使您免于创建任何自定义控件。自定义控件基本上是不必要的,因为您不会创建以前不存在的任何东西。

    <UserControl x:Class="NameSpace.SelectionView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:controls="namespace.Controls"
        Height="300" Width="300">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <TreeView Name="customTree">
                <!--Items go here-->
            </TreeView>
            <StackPanel Grid.Column="1" MinWidth="50" DataContext="{Binding ElementName=customTree, Path=SelectedItem, Mode=OneWay}">
                <StackPanel.Resources>
                    <DataTemplate DataType="{x:Type StylingTest:CustomViewModelA}">
                        <controls:CustomADetailsControl />
                    </DataTemplate>
                    <DataTemplate DataType="{x:Type StylingTest:CustomViewModelB}">
                        <controls:CustomBDetailsControl />
                    </DataTemplate>
                </StackPanel.Resources>
                <TextBlock Text="{Binding}"/>
            </StackPanel>
        </Grid>
    </UserControl>
    

    任何其他自定义行为,我相信您可以在此处创建或设置样式/模板。

    另外,您可能会发现我的其他answers 之一很有用。

    祝 wpf 好运,干杯。

    【讨论】:

    • 谢谢。这是我现在一直试图完成的,只是直接在窗口 xaml 中(不是用户控件)。虽然在堆栈面板中选择详细(用户)控件不起作用,但 TextBlock 确实显示了所选树视图项的类型。
    【解决方案3】:

    将示例中的 StackPanel 替换为 ContentPresenter,而不是 DataContext 设置 Content 属性。应该可以的。

    【讨论】:

    • 没错! DataContext 没有任何意义,它只是用于绑定。内容属性是用来呈现事物的。
    • 非常感谢。它工作得很好。关于为什么它不能使用 StackPanel 的任何输入?
    • 正如 Oleg 所说,DataContext 本身并不意味着任何东西,它只是下面的任何绑定都可以工作的地方。可以将其想象为设置要查看的堆栈框架或变量范围。您需要实际创建一个绑定并对其进行评估和显示,这就是 ContentPresenter (用于单个项目)或 ItemsPresenter (用于集合)是什么为。尝试查找 ContentPresenters 和 DataTemplates 并查看它们的实际交互方式。我不知道有什么好的博客文章,但可能有一些。
    猜你喜欢
    • 1970-01-01
    • 2011-03-22
    • 1970-01-01
    • 1970-01-01
    • 2013-05-22
    • 2016-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多