2011-02-25 54 views
1

我想使用与找到的代码类似的代码here.我遇到的问题是我想将其扩展到允许在XAML将值设置为使用{Binding PropertyOfViewModel}这样的:将在Code-Behind中通过Xaml定义的属性绑定到UserControl的DataContext中的属性

<local:TestControl> 
    <local:TestControl.TestObject> 
    {Binding PropertyOfViewModel} 
    </local:TestControl.TestObject> 
</local:TestControl> 

的问题,是它与“不能转换‘错误{结合PropertyOfViewModel}’”。 TestObject属性在视图的代码隐藏中被定义为依赖项属性。

如果我能得到它的工作,这将让我在父控件像这样写代码:

<local:TestControl x:Name="myControl" DataContext="{Binding TCViewModel}" /> 

在用户控件,这意味着我也可以绑定到暴露的命令和其他项目我TCViewModel,并且控件可以大部分是自包含的,并且所有消费者需要设置DataContext属性。


编辑

这是整个控制:

<UserControl x:Class="MyProject.Views.AddClientView" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:Views="clr-namespace:MyProject.Views" 
     Background="{StaticResource WindowBackgroundBrush}" 
     mc:Ignorable="d"> 

<!-- Comment out from here 
    <Views:AddClientView> 
    <Views:AddClientView.RenderTransform> 
     <ScaleTransform ScaleY="1" /> 
    </Views:AddClientView.RenderTransform> 
    <Views:AddClientView.IsInAcceptDataMode> 
     <Binding Path="IsInInputMode"/> 
    </Views:AddClientView.IsInAcceptDataMode> 
    <Views:AddClientView.ContentTemplate> 
     <DataTemplate> 
to here --> 
      <Grid> 
       <Label 
        Height="25" 
        Width="306" 
        HorizontalAlignment="Left" 
        Margin="12,12,0,0" 
        OverridesDefaultStyle="False" 
        Style="{DynamicResource CalloutLabel}" 
        VerticalAlignment="Top" Content="Company Name (Name of Organizational Unit)"/> 

       <TextBox Height="23" Margin="12,41,12,0" VerticalAlignment="Top" TabIndex="1" /> 

       <Button 
        Style="{DynamicResource LightButton}" 
        Height="23" Width="75" 
        HorizontalAlignment="Right" 
        VerticalAlignment="Bottom" 
        Margin="0,0,97,12" 
        TabIndex="4">OK</Button> 

       <Button 
        Style="{DynamicResource LightButton}" 
        Height="23" Width="75" 
        HorizontalAlignment="Right" 
        VerticalAlignment="Bottom" 
        Margin="0,0,12,12" 
        Command="{Binding Cancel}" 
        TabIndex="3">Cancel</Button> 

       <CheckBox Content="Make Groups" Height="16" IsChecked="True" FlowDirection="RightToLeft" Margin="150,79,12,0" VerticalAlignment="Top" TabIndex="2" /> 

       <Rectangle Fill="{DynamicResource HeaderBarFill}" Height="5" Margin="0,0,0,0" Stroke="{x:Null}" VerticalAlignment="Bottom" /> 
      </Grid> 
<!-- and here 
     </DataTemplate> 
    </Views:AddClientView.ContentTemplate> 
</Views:AddClientView> 
to here--> 

为了得到它的编译代码的建议,我不得不重新安排我的xaml,现在它在设计模式下都使Visual Studio崩溃,当我运行它时,我在视图中获得了InitializeComponent();的StackOverflow异常构造函数。


编辑2

这是把这个用户控件窗口中的代码:

<Views:AddClientView x:Name="AddClient" VerticalAlignment="Top" DataContext="{Binding AddClientVM}"> 
</Views:AddClientView> 

有趣的是:如果我从窗口中删除该代码,它运行/编译OK 。如果我从视图中删除所有<Views:AddClientView...>类型的代码,它也会运行OK。但是没有做我想做的事,因为我无法将我的DP绑定到DataContext。

如果我改变用户控件的下面,一切编译罚款,我只是失去了我的代码隐藏绑定依赖项属性:

<UserControl 
    x:Class="Mage.Views.AddClientView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:Views="clr-namespace:Mage.Views" 
    Background="{StaticResource WindowBackgroundBrush}" 
    mc:Ignorable="d" d:DesignWidth="320" d:DesignHeight="145" 
    x:Name="AddClientV" 
    MaxHeight="145" MinHeight="145"> 

    <VisualStateManager.VisualStateGroups> 
     <VisualStateGroup> 
      <VisualState x:Name="Show"> 
       <VisualState.Storyboard> 
        <Storyboard> 
        <DoubleAnimation 
          Storyboard.TargetProperty="RenderTransform.(ScaleTransform.ScaleY)" 
          Storyboard.TargetName="AddClientV" 
          From="0" 
          To="1" 
          Duration="0:0:1" /> 
        </Storyboard> 
       </VisualState.Storyboard> 
      </VisualState> 

      <VisualState x:Name="Hide"> 
       <VisualState.Storyboard> 
        <Storyboard> 
        <DoubleAnimation 
         Storyboard.TargetProperty="RenderTransform.(ScaleTransform.ScaleY)" 
         Storyboard.TargetName="AddClientV" 
         From="1" 
         To="0" 
         Duration="0:0:1" /> 
        </Storyboard> 
       </VisualState.Storyboard> 
      </VisualState> 
     </VisualStateGroup> 
    </VisualStateManager.VisualStateGroups> 

    <Views:AddClientView> 
     <Views:AddClientView.RenderTransform> 
      <ScaleTransform ScaleY="1" /> 
     </Views:AddClientView.RenderTransform> 
     <Views:AddClientView.IsInAcceptDataMode> 
      <Binding Path="IsInInputMode"/> 
     </Views:AddClientView.IsInAcceptDataMode> 
     <Views:AddClientView.ContentTemplate> 
      <DataTemplate> 
       <Grid> 
        <Label 
         Height="25" 
         Width="306" 
         HorizontalAlignment="Left" 
         Margin="12,12,0,0" 
         OverridesDefaultStyle="False" 
         Style="{DynamicResource CalloutLabel}" 
         VerticalAlignment="Top" Content="Company Name (Name of Organizational Unit)"/> 

        <TextBox Height="23" Margin="12,41,12,0" VerticalAlignment="Top" TabIndex="1" /> 

        <Button 
         Style="{DynamicResource LightButton}" 
         Height="23" Width="75" 
         HorizontalAlignment="Right" 
         VerticalAlignment="Bottom" 
         Margin="0,0,97,12" 
         TabIndex="4">OK</Button> 

        <Button 
         Style="{DynamicResource LightButton}" 
         Height="23" Width="75" 
         HorizontalAlignment="Right" 
         VerticalAlignment="Bottom" 
         Margin="0,0,12,12" 
         Command="{Binding Cancel}" 
         TabIndex="3">Cancel</Button> 

        <CheckBox Content="Make Groups" Height="16" IsChecked="True" FlowDirection="RightToLeft" Margin="150,79,12,0" VerticalAlignment="Top" TabIndex="2" /> 

        <Rectangle Fill="{DynamicResource HeaderBarFill}" Height="5" Margin="0,0,0,0" Stroke="{x:Null}" VerticalAlignment="Bottom" /> 
       </Grid> 
      </DataTemplate> 
     </Views:AddClientView.ContentTemplate> 
    </Views:AddClientView> 
</UserControl> 

代码隐藏依赖项属性:

public bool IsInAcceptDataMode 
    { 
     get { return (bool)GetValue(IsInAcceptDataModeProperty); } 
     set 
     { 
      SetValue(IsInAcceptDataModeProperty, value); 

      if (value) 
      { 
       VisualStateManager.GoToState(this, "Show", false); 
      } 
      else 
      { 
       VisualStateManager.GoToState(this, "Hide", false); 
      } 
     } 
    } 

    public static readonly DependencyProperty IsInAcceptDataModeProperty = 
     DependencyProperty.Register("IsInAcceptDataMode", typeof(bool), typeof(AddClientView), new UIPropertyMetadata(false, null)); 

编辑3

所以我被告知,基于XAML的绑定存在问题,我试图转向代码隐藏,但仍然无法实现。所以,我正在寻找一种基于代码隐藏的方式来将我的DependencyProperty绑定到ViewModel中指定给我的UserControl的DataContext的项目。

+1

可以显示包含此UserControl的视图吗?我没有注意到您提供的代码有任何问题。 – 2011-02-25 20:55:33

+0

是的,我已更新该帖子。感谢您的帮助。 – Nate 2011-02-25 21:03:17

+0

你说的代码隐藏依赖项属性在哪里?我没有在代码中看到它。 – 2011-02-25 21:54:49

回答

1

如果我正确地理解了一切,那么你需要的是一个标准的MVVM场景和标准绑定。

这是可以做到无论是这样的:

<local:TestControl TestObject="{Binding PropertyOfViewModel}"> 
</local:TestControl> 

或者这样:

<local:TestControl> 
    <local:TestControl.TestObject> 
    <Binding Path="PropertyOfViewModel"/> 
    </local:TestControl.TestObject> 
</local:TestControl> 

更新:在回答你的UserControl你已经证明......

代码

你正在做的是将一个控件放在它自己内部,这显然会给你一个StackOverflow异常。 您不需要在UserControl内定义ContentTemplate。您可以直接将内容作为子元素放置:

<UserControl 
    x:Class="Mage.Views.AddClientView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:Views="clr-namespace:Mage.Views" 
    Background="{StaticResource WindowBackgroundBrush}" 
    mc:Ignorable="d" d:DesignWidth="320" d:DesignHeight="145" 
    x:Name="AddClientV" 
    MaxHeight="145" MinHeight="145"> 

    <VisualStateManager.VisualStateGroups> 
     <VisualStateGroup> 
      <VisualState x:Name="Show"> 
       <VisualState.Storyboard> 
        <Storyboard> 
        <DoubleAnimation 
          Storyboard.TargetProperty="RenderTransform.(ScaleTransform.ScaleY)" 
          Storyboard.TargetName="AddClientV" 
          From="0" 
          To="1" 
          Duration="0:0:1" /> 
        </Storyboard> 
       </VisualState.Storyboard> 
      </VisualState> 

      <VisualState x:Name="Hide"> 
       <VisualState.Storyboard> 
        <Storyboard> 
        <DoubleAnimation 
         Storyboard.TargetProperty="RenderTransform.(ScaleTransform.ScaleY)" 
         Storyboard.TargetName="AddClientV" 
         From="1" 
         To="0" 
         Duration="0:0:1" /> 
        </Storyboard> 
       </VisualState.Storyboard> 
      </VisualState> 
     </VisualStateGroup> 
    </VisualStateManager.VisualStateGroups> 

    <Views:AddClientView.RenderTransform> 
      <ScaleTransform ScaleY="1" /> 
    </Views:AddClientView.RenderTransform> 
    <Views:AddClientView.IsInAcceptDataMode> 
      <Binding Path="IsInInputMode"/> 
    </Views:AddClientView.IsInAcceptDataMode> 

    <Grid> 
     <Label 
     Height="25" 
     Width="306" 
     HorizontalAlignment="Left" 
     Margin="12,12,0,0" 
     OverridesDefaultStyle="False" 
     Style="{DynamicResource CalloutLabel}" 
     VerticalAlignment="Top" Content="Company Name (Name of Organizational Unit)"/> 

    <TextBox Height="23" Margin="12,41,12,0" VerticalAlignment="Top" TabIndex="1" /> 

    <Button 
     Style="{DynamicResource LightButton}" 
     Height="23" Width="75" 
     HorizontalAlignment="Right" 
     VerticalAlignment="Bottom" 
     Margin="0,0,97,12" 
     TabIndex="4">OK</Button> 

    <Button 
     Style="{DynamicResource LightButton}" 
     Height="23" Width="75" 
     HorizontalAlignment="Right" 
     VerticalAlignment="Bottom" 
     Margin="0,0,12,12" 
     Command="{Binding Cancel}" 
     TabIndex="3">Cancel</Button> 

    <CheckBox Content="Make Groups" Height="16" IsChecked="True" FlowDirection="RightToLeft" Margin="150,79,12,0" VerticalAlignment="Top" TabIndex="2" /> 

    <Rectangle Fill="{DynamicResource HeaderBarFill}" Height="5" Margin="0,0,0,0" Stroke="{x:Null}" VerticalAlignment="Bottom" /> 
    </Grid> 
</UserControl> 
+0

当我运行该项目时,添加该代码会给我一个StackOverflow异常。我正在从我的控件(它只有几行)中删除名称说明,并且我会发布整个内容,也许我的其他内容有冲突并导致我的问题。 – Nate 2011-02-25 20:31:51

+0

非常感谢您花时间在此。随着你更新的代码,VS不再崩溃,我不再得到StackOverflow ....但我不得不删除'Views:AddClientView..'代码来让它编译,错误是:可附加属性'在'AddClientView'类型中找不到'RenderTransform'。 - 我得到了IsInAcceptDataMode的相同错误。有什么想法吗? – Nate 2011-02-25 23:05:00

+0

@Nate - 是的...只记得有一个已知的问题,用XAML定制自定义用户控件中定义的属性......你将无法做到这一点。相反,您必须从代码隐藏设置这个绑定,例如在构造函数中:SetBinding(IsInAcceptDataModeProperty,“IsInInputMode”)。至于RenderTransoform,只需将替换为即可。 – 2011-02-25 23:17:07

相关问题