【问题标题】:Issues in WP7 binding to properties in custom User ControlWP7 绑定到自定义用户控件中的属性的问题
【发布时间】:2012-03-19 01:08:46
【问题描述】:

所以我正在尝试为 Windows Phone 7 应用程序创建一个自定义用户控件,我称之为 ColoredTextBlock。你大概可以猜到它的作用。

无论如何,ColoredTextBlock 包含一个 TextBlock,我希望用户能够为其设置文本和样式。

如果我尝试只创建一个简单的属性,例如:

    public string Text
    {
        get { return Label.Text; }
        set
        {
            Label.Text = value;
            NotifyPropertyChanged("Text");
        }
    }

它会导致一个非常神秘的 ArgumentException。但是,如果我设置输入文本,例如:

 <MyRepresentative:ColoredTextBlock Text="Some Text" BackgroundColor="Red" />

一切都如我所料。

另一方面,如果我采用更高级的方法,即使用 Dependency 属性并将内部 TextBlock 绑定到此属性,然后将外部数据也绑定到此属性,则什么都不会显示。

    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set
        {
            SetValue(TextProperty, value);
            NotifyPropertyChanged("Label");
        }
    }

    public static readonly DependencyProperty TextProperty =
    DependencyProperty.Register("Text", typeof(string), typeof(ColoredTextBlock), null);

同样,如果我手动插入文本,整个事情就可以正常工作。

这是我的自定义控件的 xaml:

 <UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="MyRepresentative.ColoredTextBlock"
d:DesignWidth="456" d:DesignHeight="43"
    DataContext="{Binding RelativeSource={RelativeSource Self}}">

    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Rectangle Stroke="Black">
            <Rectangle.Fill>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="{Binding DimBackgroundColor}" Offset="0"/>
                    <GradientStop Color="{Binding BrightBackgroundColor}" Offset="0.85"/>
                    <GradientStop Color="{Binding BrightBackgroundColor}" Offset="0.15"/>
                    <GradientStop Color="{Binding DimBackgroundColor}" Offset="1"/>
                </LinearGradientBrush>
            </Rectangle.Fill>
        </Rectangle>
        <TextBlock Text="{Binding Text}" Margin="5,0" d:LayoutOverrides="Width"/>
    </Grid>
 </UserControl>

我在这一天的大部分时间里都在为此绞尽脑汁,看了这么多不同的文章,我确定在这一点上我错过了一些小东西,但我就是不能找到它。

更新 1:在进一步研究之后,似乎出于某种原因,即使我使用绑定进行了设置,但似乎并没有实际设置,至少到目前为止据我所知。

更新 2:根据评论,您询问是否确保我的 DataContext 设置正确。是的,这是我首先想到的事情之一。我的 xaml 下面有一行。

 <MyRepresentative:ColoredTextBlock Text="{Binding Title}" BackgroundColor="Red" />
 <TextBlock Text="{Binding Title}" Style="{StaticResource PhoneTextLargeStyle}" />

所以第一个元素(根本)不会出现,除非我更改为 Text="Some text" 之类的东西。第二个元素完美无误。

【问题讨论】:

  • 您没有包含设置 DataContext 的代码(以便您的 {Binding} 工作)。另外,您是否通知了错误的属性名称? (您在名为“Text”的属性上调用 NotifyPropertyChanged("Label"))
  • 嘿Shahar,我试图在上面的更新中解决您的评论。名称的问题是因为我尝试了许多不同的方法来让它发挥作用。但是,我确实确保它们现在是一致的。
  • 我的意思是您的数据上下文在您的控制范围内。您在顶部引用自己 - 但在您的示例代码中,您绑定到“标题”并且在控件中您绑定到“文本”
  • 因此具有实际文本的 ViewModel 元素是 Title。我将它绑定到我的 UserControl 上的 Text 属性,并且我还将 TextBlock 的 Text 属性绑定到我的 UserControl 的 Text 属性。希望能解决一些困惑。
  • Gotcha - 所以这可能只是我在这里缺乏理解......你在那里的RelativeSource Self本质上指向控件的DataSource(而不是this [控件实例] 将拥有你的属性)?通过阅读RelativeSource,这就是我所收集的。您是否尝试将控件中的绑定更改为 {Title} 只是为了看看它是否有效?

标签: windows-phone-7 user-controls


【解决方案1】:

我在做与自己相同的事情时遇到了一些真正的麻烦,没有运气,我发现的唯一条目谈到这种方法不起作用(抱歉,我再也找不到它们了)。

如果我通过 C# 设置绑定,我确实成功了。我有一个 shared here 的例子。

编辑:我刚刚找到的另一个解决方案是使用Element Name bindings

【讨论】:

  • 感谢您的建议。我检查了他们两个。不幸的是,他们似乎没有给我比我现在得到的更好的结果:(
【解决方案2】:

我最终自己找出了这个问题的答案,尽管我花了一些时间和一些搜索。答案实际上是受到this answer 的启发。

答案:

而不是使用以下方式绑定到根元素:

 DataContext="{Binding RelativeSource={RelativeSource Self}}" 

就像我在上面的例子中所做的那样:

 <UserControl
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     mc:Ignorable="d"
     x:Class="MyRepresentative.ColoredTextBlock"
     d:DesignWidth="456" d:DesignHeight="43"
     DataContext="{Binding RelativeSource={RelativeSource Self}}">

改为绑定到 LayoutRoot,在本例中为我的 Grid 元素。

 <Grid x:Name="LayoutRoot">

这可以在你的代码后面的构造函数中完成,就像我在这里做的那样:

    public ColoredTextBlock()
    {
        ...
        LayoutRoot.DataContext = this;
        ...
    }

说明:

老实说,我不完全理解为什么这样做,如果有人可以解释,请编辑。

当您绑定到根元素时,这似乎与覆盖现有绑定有关。因此,当您尝试将外部元素绑定到此控件的元素时,它将失败,因为该绑定不可访问。

希望能帮助遇到和我一样问题的其他人!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2018-03-11
    • 2011-05-11
    相关资源
    最近更新 更多