绑定依赖项属性,在$ C $定义C-的背后,通过XAML到物业在用户控件的DataContext的 [英] Bind Dependency Property, defined in Code-Behind, through Xaml to a Property in the DataContext of a UserControl

查看:240
本文介绍了绑定依赖项属性,在$ C $定义C-的背后,通过XAML到物业在用户控件的DataContext的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用类似code发现这里的问题我遇到的是,我希望把它扩大到允许在XAML设置为使用 {结合PropertyOfViewModel} 这样的值:

I want to use code similar to that found here. The issue I'm having is that I'd like to extend it to allow the value set in the XAML to use {Binding PropertyOfViewModel} like this:

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

的问题,是与它的错误不能转换{结合PropertyOfViewModel}。在TestObject中属性被定义为在视图中的code-后面的依赖项属性。

The problem, is that it errors with "Cannot Convert "{Binding PropertyOfViewModel}"". The TestObject property is defined as a dependency property in the code-behind of the view.

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

If I can get it to work, this will allow me to write code like this in the parent control:

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

这意味着在该用户我也可以绑定到我的TCViewModel暴露的命令和其他物品,以及控制可多为自包含的,并且所有消费者需要设置DataContext属性。

Which means in the UserControl I can also bind to commands and other items exposed in my TCViewModel, and the control can be mostly self-contained, and all a consumer need to is set the DataContext property.

修改

这是整个控制:

<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-->

为了得到它的编译与code的建议,我不得不重新安排我的XAML,现在这两个崩溃的Visual Studio的设计模式,当我运行它,我得到<出现StackOverflow例外code>的InitializeComponent(); 的意见构造

In order to get it to compile with the code suggested, I had to re-arrange my xaml, now it both crashes Visual Studio in Design Mode, and when I run it, I get a StackOverflow exception on InitializeComponent(); in the Views Constructor.

修改2

这是在code,它把这个用户控件的窗口:

This is the code that puts this UserControl on the window:

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

有趣的是:如果我从窗口中删除这个code,它运行/编译确定。如果我删除所有的&LT的;浏览次数:AddClientView ...&GT; 键入code。在视图中,它也运行正常。但是没有做什么,我想要的,因为我无法将DP绑定到DataContext。

Interestingly: if I remove this code from the Window, it runs/compiles OK. If I remove all of the <Views:AddClientView...> type code from within the View, it also runs OK. But does not do what I want because I cannot bind my DP to the DataContext.

如果我的用户控件更改为以下,一切都编译好,我刚刚失去我的$ C $绑定C-背后依赖项属性:

If I change the UserControl to the below, everything compiles fine, I just loose the binding on my code-behind dependency property:

<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>

code-背后依赖项属性:

Code-Behind Dependency Property:

    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基结合,我尝试移动到code-背后的问题,我仍然不能得到它的工作。所以,我期待在这一点上为code-基于落后的方式对我的DependencyProperty绑定到其指定到我的用户的DataContext的在视图模型中的项目。

So I've been informed that there are issues with XAML based binding, I tried moving to code-behind, and I still cannot get it to work. So, I'm looking at this point for a code-behind based way to bind my DependencyProperty to an item in the ViewModel which is specified to the DataContext of my UserControl.

推荐答案

如果我明白了一切正确的,然后你需要的是一个标准的MVVM方案和标准的绑定。

If I understood everything correctly then what you need is a standard MVVM scenario and standard bindings.

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

It can be done either like this:

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

或者是这样的:

Or like this:

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

更新:为了响应的code你的用户控件您已经证明......

Update: In response to the code of your UserControl you've shown...

你所要做的是把自己的内部控制,这显然会给你一个计算器例外。 你并不需要定义一个的ContentTemplate 用户控件。您只需直接将内容作为子元素:

What you are doing is placing a control inside itself, which obviously will give you a StackOverflow exception. You don't need to define a ContentTemplate inside UserControl. You can just place the content directly as a child element:

<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>

这篇关于绑定依赖项属性,在$ C $定义C-的背后,通过XAML到物业在用户控件的DataContext的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆