Проблема привязки данных с WPF - PullRequest
2 голосов
/ 31 марта 2011

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

XAML

<UserControl x:Class="WorkDayManager3.WPF.UserControls.TimeControl"
         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" 
         d:DesignHeight="46" d:DesignWidth="133" Background="Transparent"
         DataContext="{Binding RelativeSource={RelativeSource self}}">    
<Grid Height="44" Width="132" Background="Transparent">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="29" />            
    </Grid.ColumnDefinitions>

    <TextBox Name="label" Text="{Binding Text}" Grid.ColumnSpan="5"></TextBox>

</Grid>

C #

public partial class TimeControl : UserControl
{
    public string Text
    {

        get { return (string)GetValue(TextProperty); }

        set { SetValue(TextProperty, value); }

    }

    // Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc...

    public static readonly DependencyProperty TextProperty =

    DependencyProperty.Register("Text", typeof(string), typeof(TimeControl), new UIPropertyMetadata("N/A"));

    public TimeControl()
    {
        InitializeComponent();
    }

В окне, где я использую элемент управления, он используется в сетке, для которого текст данных имеет значение StaticResource

    <Grid Grid.Row="1" HorizontalAlignment="Center" DataContext="{StaticResource shiftViewSource}" Name="grid1" Margin="48,10,38,0">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <TextBox Grid.Column="0" Grid.Row="1" Height="23" TabIndex="2" HorizontalAlignment="Left" Margin="10,5,0,5" Name="shiftNameTextBox" Text="{Binding Path=ShiftName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="120" />
        <my2:TimeControl Grid.Column="0" Grid.Row="2" Height="23" TabIndex="2" HorizontalAlignment="Left" Margin="10,5,0,5" Name="shiftNameTextBox" Text="{Binding Path=ShiftName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="120" />
        <my2:TimeControl Grid.Column="0" Grid.Row="3" Text="THIS WORKS OK"/>            
    </Grid>

Теперь TextBox, связанный с Path ShiftName, работает нормально и отображает текст. Когда я вместо этого использую свой элемент управления, он не показывает ожидаемый текст. Однако во втором примере, где я просто установил свойство зависимости текста «ЭТО РАБОТАЕТ ОК», текст отображается, как и ожидалось. Почему привязка работает для TextBox, а не для моего элемента управления. Что я делаю не так?

Ответы [ 2 ]

6 голосов
/ 31 марта 2011

Вы установили DataContext на UserControl для себя. Таким образом, привязка вашего свойства TimeControl Text пытается найти свойство с именем ShiftName в вашем TimeControl, а не в вашем статическом ресурсе. Если вы посмотрите в окно вывода Visual Studio, вы должны увидеть сообщение об ошибке на этот счет.

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

<UserControl x:Name="root" ...>
    <Grid DataContext="{Binding ElementName=root}"
        ...
0 голосов
/ 31 марта 2011

Другим способом может быть использование относительной привязки:

<Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" >
    ...
...