Проблемы привязки WP7 к свойствам в пользовательском элементе управления - PullRequest
0 голосов
/ 19 марта 2012

Поэтому я пытаюсь создать пользовательский элемент управления для приложения 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 и привязка Inner 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 : на основекомментарий, вы спросили о том, чтобы убедиться, что мy DataContext был установлен правильно.Да, это было одним из первых вещей, о которых я подумал.У меня есть строки ниже в моем xaml.

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

Таким образом, первый элемент не отображается (вообще), если я не перехожу на что-то вроде Text="Some text".Второй элемент отлично работает без ошибок.

Ответы [ 2 ]

2 голосов
/ 19 марта 2012

У меня были некоторые реальные проблемы, когда я делал то же самое, что и вы, но не повезло, единственные записи, о которых я узнал, говорили о том, что этот подход не работает (извините, я больше их не могу найти).

У меня былоуспех, если я установлю привязки через C #.У меня есть пример этого общего доступа здесь .

Редактировать : Другое решение, которое я только что нашел, состоит в использовании привязок имени элемента .

0 голосов
/ 31 марта 2012

В итоге я сам нашел ответ на эту проблему, хотя это заняло у меня некоторое время и немного поисков. Ответ был на самом деле вдохновлен этим ответом .

Ответ:

Вместо привязки к корневому элементу используется:

 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 x:Name="LayoutRoot">

Это можно сделать в вашем коде позади, в конструкторе, как я делал здесь:

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

Пояснение:

Я не совсем понимаю, почему это работает, если честно, и если кто-то может объяснить это, пожалуйста, отредактируйте.

Похоже, это связано с переопределением существующих привязок при привязке к корневому элементу. Таким образом, при попытке привязать внешний элемент к элементу этого элемента управления он потерпит неудачу, поскольку эта привязка недоступна.

Надеюсь, это поможет другим, кто сталкивается с той же проблемой, что и я!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...