【问题标题】:Contentcontrol doesn't find my datatemplate it's ViewModelContentcontrol 找不到我的数据模板,它是 ViewModel
【发布时间】:2011-12-16 12:19:16
【问题描述】:

我正在使用 WPF、MVVM 和 PRISM。 我的视图中有一个数据模板链接到 ViewModel UC2002_RFPBeheren_ViewModel,因为包含此代码的页面链接到另一个 ViewModel,我希望 Button 将 UC2002_RFPBeheren_ViewModel 作为 ViewModel。

此页面的数据上下文是 UC2002_RFPBeheren_ProjectInfo_ViewModel 但我希望 SaveButton 使用 ViewModel UC2002_RFPBeheren_ViewModel

这是我的代码:

<UserControl.Resources>
<ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="../Resources/RFPModuleResources.xaml" />
        <ResourceDictionary>
            <DataTemplate x:Key="SaveButton" DataType="{x:Type vm:UC2002_RFPBeheren_ViewModel}">
                <Button Command="{Binding SaveRFPCommand}">Save</Button>
            </DataTemplate>
        </ResourceDictionary>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>

<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
   <ContentControl ContentTemplate="{StaticResource SaveButton}"/>
   <Button Command="{Binding CloseTabCommand}">Close</Button>
</StackPanel>

虽然 SaveButton 显示但不响应我的命令。
我忘记了什么还是有其他方法可以解决这个问题?
提前致谢;)!

================================================ ===================================

编辑:

所以我做了一些更改,但它仍然不起作用。

代码示例:

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="../Resources/RFPModuleResources.xaml" />
            <ResourceDictionary>
                <DataTemplate x:Key="SaveButton" DataType="{x:Type vm:UC2002_RFPBeheren_ViewModel}">
                    <Button Command="{Binding SaveRFPCommand}">Save</Button>
                </DataTemplate>
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>

我在页面的ViewModel中设置了这个属性

public UC2002_RFPBeheren_ViewModel MySaveVM { get; set; }

我的堆栈面板现在看起来像这样:

<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
    <ContentControl Content="{Binding MySaveVM}" ContentTemplate="{StaticResource SaveButton}"/>
    <Button Command="{Binding CloseTabCommand}">Close</Button>
</StackPanel>

【问题讨论】:

  • 所以要清楚。你曾经设置过你的视图的 DataContext 吗?即 DataContext 是否设置为 UC2002_RFPBeheren_ViewModel 的实例?
  • 页面是一个用户控件,一个tabitem,datacontext是用这个代码设置的:
  • 因此,如果 DataContext 是您的 ViewModel,那么我在您将 ContentControl 的内容设置为“{Binding}”的位置给出的答案应该可以工作。
  • 我不希望页面的主要数据上下文成为按钮的数据上下文。我想要按钮上的差异数据上下文而不是主按钮。
  • 所以上面StackPanel的DataContext是UC2002_RFPBeheren_ProjectInfo_ViewModel。并且大概具有 CloseTabCommand 属性,因为这是您将 Button 兄弟绑定到相关 ContentControl 的内容。在您用于 ContentControl 的模板中,您将绑定到名为 SaveRFPCommand 的属性。什么对象定义了该属性?如果这也在 UC2002_RFPBeheren_ProjectInfo_ViewModel 上,那么您确实希望将其用作 DataContext。如果那不在其上的子对象上,那么您将绑定到返回该子对象的属性。

标签: c# wpf xaml mvvm prism


【解决方案1】:

如果您将 UV2002_RFPBeheren_ViewModel 实例设置为 ContentPresenter 的内容会发生什么?

 <ContentControl Content="{Binding MyUV2002_RFPBeheren_ViewModel}"/>

DataTemplate 只是说明您的 Viewmodel 应该如何显示,但您必须将 DataContext 或 Binding 设置为 viewmodel 的实例。

编辑:

例子

 public class VMFoo
 {
     public UV2002_RFPBeheren_ViewModel MySaveVM {get; set;}
 }

xml

<UserControl.Resources>
<ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="../Resources/RFPModuleResources.xaml" />
        <ResourceDictionary>
            <DataTemplate x:Key="SaveButton" DataType="{x:Type vm:UC2002_RFPBeheren_ViewModel}">
                <Button Command="{Binding SaveRFPCommand}">Save</Button>
            </DataTemplate>
        </ResourceDictionary>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<UserControl.DataContext>
   <x:local VMFoo/>
</UserControl.DataContext>
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
   <ContentControl Content="{Binding MySaveVM}"/>
   <Button Command="{Binding CloseTabCommand}">Close</Button>
</StackPanel>

编辑:小型工作样本

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:WpfApplication1="clr-namespace:WpfApplication1" Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <ResourceDictionary>
        <DataTemplate DataType="{x:Type WpfApplication1:UV2002_RFPBeheren_ViewModel}">
            <Button Command="{Binding SaveRFPCommand}">Save</Button>
        </DataTemplate>
    </ResourceDictionary>
</Window.Resources>
<Grid> 
    <Grid.DataContext>
        <WpfApplication1:VMFoo/>
    </Grid.DataContext>
    <StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
        <ContentControl Content="{Binding MySaveVM}"/>
        <Button Command="{Binding CloseTabCommand}">Close</Button>
    </StackPanel>
</Grid>
</Window>

视图模型

public class VMFoo
{
    public VMFoo()
    {
        this.MySaveVM = new UV2002_RFPBeheren_ViewModel();
    }
    public UV2002_RFPBeheren_ViewModel MySaveVM { get; set; }
}

public class UV2002_RFPBeheren_ViewModel
{
    private DelegateCommand _save;
    public ICommand SaveRFPCommand
    {
        get{if(this._save==null)
        {
            this._save = new DelegateCommand(()=>MessageBox.Show("success"),()=>true);
        }
            return this._save;
        }
    }
}

【讨论】:

  • 所以我将其更改为 但它仍然没有出现在我的 ViewModel 的断点中
  • 您不需要 ContentTemplate,但您需要一个视图模型的实例。并且此实例应绑定为您的内容控件的内容。因此,如果您的数据上下文是 VMFoo,那么您需要在 VMFoo 中绑定一个 UV2002_RFPBeheren_ViewModel 类型的公共属性。
  • 我做了更改检查我的问题我知道你的意思,但我猜还是有问题
【解决方案2】:

这是因为 ContentControl 的工作方式。假设 ContentTemplate 中的内容与 Content 相关,因此 DataContext 设置为 Content,因此这是模板中的按钮可以访问的 DataContext。您尚未指定 Content,因此值为 null,因此 DataContext 显式设置为 null。您可以在一个基本示例中看到这一点。您可以做的一件事是将 ContentControl 的内容绑定到 DataContext - 请参阅示例中的最后一个内容控件。

<StackPanel DataContext="Foo">  
  <StackPanel.Resources>
    <DataTemplate x:Key="withBtn">
      <Button Content="{Binding}" />
    </DataTemplate>
  </StackPanel.Resources>
  <Button Content="{Binding}" />
  <ContentControl ContentTemplate="{StaticResource withBtn}" />
  <ContentControl Content="{Binding}" ContentTemplate="{StaticResource withBtn}" />
</StackPanel>

【讨论】:

    【解决方案3】:

    如果您使用 MVVM,则必须在 UC2002_RFPBeheren_ProjectInfo_ViewModel 中公开一些 UC2002_RFPBeheren_ViewModel 实例以进行绑定。作为属性,或者作为属性的集合的项目。

    视图中的所有内容都必须最终可以从作为数据上下文的 ViewModel 访问 (UC2002_RFPBeheren_ProjectInfo_ViewModel)

    【讨论】:

    • 在按钮声明中丢失 DataContext="MySaveVM"。在 ContentControl 上的绑定中,模板的上下文已设置为 MySaveVM。您应该能够在输出窗口中看到绑定错误,这有助于诊断此类问题。
    • Don't get mutch help from my output dialog it says: The thread '' (0x1fbc) has exited with code 0 (0x0).
    猜你喜欢
    • 2011-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    相关资源
    最近更新 更多