Свойство зависимости привязки, определенное в Code-Behind, через Xaml со свойством в DataContext элемента UserControl - PullRequest
1 голос
/ 25 февраля 2011

Я хочу использовать код, подобный найденному здесь. Проблема, с которой я столкнулся, заключается в том, что я хотел бы расширить его, чтобы позволить значению, установленному в XAML, использовать {Binding PropertyOfViewModel}, как это:

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

Проблема состоит в том, что это приводит к ошибкам с "Cannot Convert" {Binding PropertyOfViewModel} "".Свойство TestObject определено как свойство зависимостей в выделенном фрагменте кода представления.

Если я смогу заставить его работать, это позволит мне написать такой код в родительском элементе управления:

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

Это означает, что в UserControl я также могу связываться с командами и другими элементами, представленными в моем TCViewModel, и элемент управления может быть в основном автономным, и все, что нужно потребителю, это установить свойство DataContext.


edit

Это весь элемент управления:

<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 в режиме конструктора, и при запуске я получаю исключение StackOverflow для InitializeComponent(); в конструкторе представлений.


edit 2

Это код, который помещает этот UserControl в окно:

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

Интересно: если я удаляю этот код из окна, он запускается / компилируется нормально,Если я удаляю весь код типа <Views:AddClientView...> из представления, он также работает нормально.Но не делает то, что я хочу, потому что я не могу связать свой DP с DataContext.

Если я изменю UserControl на приведенный ниже, все компилируется нормально, я просто теряю привязку в свойстве зависимостей code-behind:

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

edit 3

Итак, мне сообщили, что существуют проблемыс привязкой на основе XAML я попытался перейти к выделенному коду и до сих пор не могу заставить его работать.Итак, я смотрю на данный момент для основанного на коде способа связывания моего DependencyProperty с элементом в ViewModel, который указан в DataContext моего UserControl.

1 Ответ

1 голос
/ 25 февраля 2011

Если я все правильно понял, то вам нужен стандартный сценарий MVVM и стандартные привязки.

Это можно сделать так:

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

Или вот так:

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

Обновление: В ответ на код вашего UserControl вы показали ...

Что вы делаете, так это помещаете элемент управления внутрь себя, что, очевидно, даст вам исключение StackOverflow. Вам не нужно определять ContentTemplate внутри UserControl. Вы можете просто разместить контент непосредственно как дочерний элемент:

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...