2011-02-25 51 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

相關問題