【问题标题】:chaining dependency properties xaml wpf链接依赖属性 xaml wpf
【发布时间】:2014-08-30 02:02:07
【问题描述】:

我有一个希望通过其父 xaml 访问的用户控件(在本例中为 wpf 页面)。我的用户控件有一个标签属性,我希望通过将其绑定到传递到页面 xaml 的数据上下文来通过页面 xaml 进行设置。

目前,在下面的示例中,来自页面 xaml 的数据绑定似乎工作正常。我可以通过页面 xaml 设置用户控件标签的内容,只要我不尝试将其绑定到页面数据上下文,当我尝试这样做时,标签总是显示为空白。

我已经关注了该站点上建议的许多其他相关示例,但到目前为止还没有确定我哪里出错了。任何建议将不胜感激。

用户控件 XAML

<UserControl x:Class="Pipeline_General.Custom_Controls.AttributeStack"
         xmlns:pm="clr-namespace:Pipeline_General"
         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" 
         mc:Ignorable="d"
         DataContext = "{Binding RelativeSource={RelativeSource Self}}"
         d:DesignHeight="30" d:DesignWidth="300">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="2*" />
        <ColumnDefinition Width="3*" />
    </Grid.ColumnDefinitions>
    <Label Foreground="{x:Static pm:myBrushes.pink}" Content="{Binding Path=Attr}"  Grid.Column="0" HorizontalAlignment="Right" FontFamily="Calibri" FontSize="14" Margin="5,0,5,0"/>
    <Label x:Name="ValLabel" Foreground="{x:Static pm:myBrushes.blue}" Grid.Column="1" HorizontalAlignment="Left" FontFamily="Calibri" FontSize="14" Margin="5,0,5,0"/>
</Grid>

后面的用户控制代码

public partial class AttributeStack : UserControl
{


    public static readonly DependencyProperty AttrProperty = DependencyProperty.Register
        (
             "Attr",
             typeof(string),
             typeof(AttributeStack),
             new PropertyMetadata(string.Empty)
        );

    public static readonly DependencyProperty ValProperty = DependencyProperty.Register
            (
                 "Val",
                 typeof(string),
                 typeof(AttributeStack),
                 new PropertyMetadata(string.Empty)
            );

    public static readonly DependencyProperty ValTextProperty = DependencyProperty.Register
        (
                "ValText",
                typeof(string),
                typeof(AttributeStack),
                new PropertyMetadata(string.Empty)
        );

    public string Val
    {
        get { return (string)GetValue(ValProperty); }
        set { SetValue(ValProperty, value); }
    }

    public string ValText
    {
        get { return (string)GetValue(ValTextProperty); }
        set { SetValue(ValTextProperty, value); }
    }


    public string Attr
    {
        get { return (string)GetValue(AttrProperty); }
        set { SetValue(AttrProperty, value); }
    }


    public AttributeStack()
    {
        InitializeComponent();

        Binding valBinding = new Binding("Val")
        {
            Source = Val,
            Mode = BindingMode.OneWay
        };

        Binding textBinding = new Binding("Content")
        {
            Source = this.ValLabel.Content,
            Mode = BindingMode.OneWay
        };

        ValLabel.SetBinding(Label.ContentProperty, valBinding);
        this.SetBinding(AttributeStack.ValTextProperty, textBinding);
    }
}

页面 XAML

<Page x:Class="Pipeline_General.SceneView" x:Name="page"
  xmlns:pm="clr-namespace:Pipeline_General"
  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" 
  mc:Ignorable="d" 
  xmlns:cc="clr-namespace:Pipeline_General.Custom_Controls"
  d:DesignHeight="800" d:DesignWidth="600"
  DataContext = "{Binding RelativeSource={RelativeSource Self}}"
  Title="SceneView">
<Grid>
    <ScrollViewer>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <StackPanel Grid.Column="0">
                <Expander IsExpanded="True" Margin="5">
                    <Expander.Header>
                        <Grid x:Name="Grid" HorizontalAlignment="Stretch" Width="NaN">
                            <Border x:Name="Border" Background="Transparent" HorizontalAlignment="Stretch" BorderBrush="{x:Static pm:myBrushes.blue}" BorderThickness="0,0,0,1"
                        Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Expander}}, Path=ActualWidth}">
                                <TextBlock x:Name="HeaderText" FontSize ="18" FontFamily="Calibri" Foreground="{x:Static pm:myBrushes.blue}" Text="General Info: " />
                            </Border>
                        </Grid>
                    </Expander.Header>
                    <StackPanel>
                        <Separator Foreground="Transparent" Height="0" Margin="5"/>
                        <cc:AttributeStack Attr="Title:" Val="{Binding Path=DataContext.Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/>
                        <Separator Foreground="Transparent" Height="0" Margin="5"/>
                        <cc:AttributeStack Attr="Episode:" Val="{Binding Path=DataContext.episode.Key, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/>
                        <cc:AttributeStack Attr="Sequence:" Val="{Binding Path=DataContext.sequence.Key, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/>
                        <cc:AttributeStack Attr="Scene:" Val="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/>
                        <Separator Foreground="Transparent" Height="0" Margin="5"/>
                        <cc:AttributeStack Attr="Assigned:" Val="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/>
                        <cc:AttributeStack Attr="Status:" Val="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/>
                        <Separator Foreground="Transparent" Height="0" Margin="5"/>
                        <cc:AttributeStack Attr="Last Saved (Time):" Val="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/>
                        <cc:AttributeStack Attr="Last Saved (User):" Val="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/>
                        <Separator Foreground="Transparent" Height="0" Margin="5"/>
                        <cc:AttributeStack Attr="Due:" Val="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/>
                    </StackPanel>
                </Expander>
            </StackPanel>

            <StackPanel Grid.Column="1">
                <cc:Playblast_Viewer  x:Name="PlayblastView"/>
                <cc:FeedbackCtrl Header="Feedback:"/>
                <cc:FeedbackCtrl Header="NoticeBoard:"/>
            </StackPanel>

        </Grid>
    </ScrollViewer>
</Grid>

绑定到 DataContext.Title 字段的标签似乎正在工作,并且设置 attr 字段似乎也正常/按预期工作。因此,我无法工作的只是 Val 字段..

已更新以包含后面的页面代码。不过这里几乎没有发生任何事情。

public partial class SceneView : Page
{
    public Scene scene { get; set; }
    public SceneView(Scene s)
    {
        InitializeComponent();
        scene = s;
        this.DataContext = scene;
    }
}

我知道我在 DP 中很新,所以很有可能我尝试做的事情可以用完全不同的方式做得更好。在这种情况下,场景对象具有大量字段,我使用页面和用户控件来公开这些字段。我已经在没有任何 xaml 的代码中编写了整个应用程序,但现在我正在尝试自学 xaml 并让下一个版本的原型更加流畅,并将所需的编码减少 80%。

场景对象,它是页面对象的数据上下文,我试图将字段发送到用户控件,即。 page.DataContext.episode.Key 是后面代码中的合法字段。通过上面的 xaml,我正在寻找将其值发送到 Val 字段,然后更新 ValText(用户控件中的标签)内容属性。

【问题讨论】:

  • 链接/接线从来都不是依赖属性的问题。对我来说,你的逻辑似乎有点纠结。我发现有点难以想象想要的东西。如果你能画出同样的东西,我们将不胜感激。 IE。财产来源、调解人和目标。
  • 你能分享一下页面背后的代码吗?
  • 是的,我已经看过这个页面并使用 relativesource 为页面 datacontext 设置适当的数据上下文,因为这个问题最初是发布的.. 仍然没有工作

标签: c# wpf xaml


【解决方案1】:

我已经解决了问题。其中大多数是因为我仍然是 xaml 的新手。

我意识到如果未使用 get/set 访问器声明数据上下文,则它们不会访问字段。我在后面的页面代码中更改了场景声明,使其成为依赖对象 我没有使用链接绑定,而是使用依赖属性更改事件来设置用户控件标签内容。

public partial class AttributeStack : UserControl
{
    #region Val (DependencyProperty)
    public string Val
    {
        get { return (string)GetValue(ValProperty); }
        set { SetValue(ValProperty, value); }
    }
    public static readonly DependencyProperty ValProperty =
        DependencyProperty.Register("Val", typeof(string), typeof(AttributeStack),
          new PropertyMetadata { PropertyChangedCallback = ValChanged });
    private static void ValChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        AttributeStack aStack = d as AttributeStack;
        if (aStack != null && e.NewValue != null)
        {
            aStack.ValLabel.Content = e.NewValue.ToString();
        }
    }
    #endregion

    public static readonly DependencyProperty AttrProperty = DependencyProperty.Register
        (
             "Attr",
             typeof(string),
             typeof(AttributeStack),
             new PropertyMetadata(string.Empty)
        );

    public string Attr
    {
        get { return (string)GetValue(AttrProperty); }
        set { SetValue(AttrProperty, value); }
    }

    public AttributeStack()
    {
        InitializeComponent();
    }
}

}

public partial class SceneView : Page
{
    public static readonly DependencyProperty sceneProperty = DependencyProperty.Register
        (
             "scene",
             typeof(Scene),
             typeof(SceneView)
        );

    public Scene scene
    {
        get { return (Scene)GetValue(sceneProperty); }
        set { SetValue(sceneProperty, value); }
    }
    public SceneView(Scene s)
    {
        InitializeComponent();
        scene = s;

        this.DataContext = scene;
    }
}

<Page x:Class="Pipeline_General.SceneView" x:Name="page"
  xmlns:pm="clr-namespace:Pipeline_General"
  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" 
  mc:Ignorable="d" 
  xmlns:cc="clr-namespace:Pipeline_General.Custom_Controls"
  d:DesignHeight="800" d:DesignWidth="600"
  DataContext = "{Binding RelativeSource={RelativeSource Self}}"
  Title="SceneView">
<Grid>
    <ScrollViewer>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <StackPanel Grid.Column="0">
                <Expander IsExpanded="True" Margin="5">
                    <Expander.Header>
                        <Grid x:Name="Grid" HorizontalAlignment="Stretch" Width="NaN">
                            <Border x:Name="Border" Background="Transparent" HorizontalAlignment="Stretch" BorderBrush="{x:Static pm:myBrushes.blue}" BorderThickness="0,0,0,1"
                        Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Expander}}, Path=ActualWidth}">
                                <TextBlock x:Name="HeaderText" FontSize ="18" FontFamily="Calibri" Foreground="{x:Static pm:myBrushes.blue}" Text="General Info: " />
                            </Border>
                        </Grid>
                    </Expander.Header>
                    <StackPanel>
                        <Separator Foreground="Transparent" Height="0" Margin="5"/>
                        <cc:AttributeStack Attr="Title:" Val="{Binding Path=scene.Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/>
                        <Separator Foreground="Transparent" Height="0" Margin="5"/>
                        <cc:AttributeStack Attr="Episode:" Val="{Binding Path=scene.episode.Key, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/>
                        <cc:AttributeStack Attr="Sequence:" Val="{Binding Path=scene.sequence.Key, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/>
                        <cc:AttributeStack Attr="Scene:" Val="{Binding Path=scene.Key, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/>
                        <Separator Foreground="Transparent" Height="0" Margin="5"/>
                        <cc:AttributeStack Attr="Assigned:" Val="{}"/>

                        <cc:AttributeStack Attr="Status:" Val="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/>
                        <Separator Foreground="Transparent" Height="0" Margin="5"/>
                        <cc:AttributeStack Attr="Last Saved (Time):" Val="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/>
                        <cc:AttributeStack Attr="Last Saved (User):" Val="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/>
                        <Separator Foreground="Transparent" Height="0" Margin="5"/>
                        <cc:AttributeStack Attr="Due:" Val="{Binding Path=Title, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Page}}"/>
                    </StackPanel>
                </Expander>
            </StackPanel>

            <StackPanel Grid.Column="1">
                <cc:Playblast_Viewer  x:Name="PlayblastView"/>
                <cc:FeedbackCtrl Header="Feedback"/>
                <cc:FeedbackCtrl Header="NoticeBoard"/>
            </StackPanel>

        </Grid>
    </ScrollViewer>
</Grid>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-20
    • 1970-01-01
    • 2014-05-23
    • 2015-08-25
    • 2013-01-27
    • 1970-01-01
    相关资源
    最近更新 更多