Привязка не работает в ListView - PullRequest
1 голос
/ 08 июня 2010

У меня есть элемент управления wpf с именем DataPicker, у которого есть свойство зависимости с именем SelectedDate.

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

Например, у меня есть класс (реализован INotifyPropertyChanged)

public class TestClass : INotifyPropertyChanged
{
    public string Name { get; set; }
    public DateTime Date { get; set; }
}

и попробуйте связать коллекцию образцов как

public ObservableCollection<TestClass> Items { get; set; }

, в котором есть один элемент.

Обвязка выглядит как

 <Window x:Class="Neverov.Test.Window1"
         x:Name="this"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:Neverov.Framework;assembly=Neverov.Framework">
     <Grid>        
         <ListView ItemsSource="{Binding ElementName=this, Path=Items}">
             <ListView.ItemTemplate>
                 <DataTemplate>                     
                     <StackPanel>
                         <TextBlock Text="{Binding Name}"/>
                             <local:DatePicker SelectedDate="{Binding Date, Mode=TwoWay}"/>                             
                     </StackPanel>                     
                 </DataTemplate>
             </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Window>

и свойство Name работает нормально.

внутри моего DatePicker значение даты показано так:

<TextBox x:Name="PART_TextBox">
    <TextBox.Text>
        <Binding Path="SelectedDate" 
                 RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type local:DatePicker}}"
                 Mode="TwoWay"
                 Converter="{StaticResource DateTimeConverter}"
                 ConverterParameter="d">
        </Binding>
    </TextBox.Text>    
</TextBox>

есть идеи, почему это могло произойти?

Еще код класса DatePicker: (некоторые специфические свойства, которые мне нужны, я скорее пропущу, чтобы размер кода не был таким большим)

[TemplatePart(Name = PartPopup, Type = typeof(Popup))]
[TemplatePart(Name = PartMonthBack, Type = typeof(ButtonBase))]
[TemplatePart(Name = PartMonthForward, Type = typeof(ButtonBase))]
[TemplatePart(Name = PartDates, Type = typeof(Selector))]
[TemplatePart(Name = PartTextBox, Type = typeof(TextBox))]
[TemplatePart(Name = PartCheckBox, Type = typeof(CheckBox))]
[TemplatePart(Name = PartToggleButton, Type = typeof(ToggleButton))]
public class DatePicker : Control, INotifyPropertyChanged
{
    ...
    public static readonly DependencyProperty SelectedDateProperty =
        DependencyProperty.Register("SelectedDate",
                                    typeof(DateTime?),
                                    typeof(DatePicker),
                                    new FrameworkPropertyMetadata(null,
                                                                  FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                                                                  (sender, e) =>
                                                                  {
                                                                      var datePicker = sender as DatePicker;
                                                                      if (datePicker != null)
                                                                      {
                                                                          var oldValue = e.OldValue as DateTime?;
                                                                          DateTime selectedDateForPopup =
                                                                              datePicker.SelectedDate ??
                                                                              DateTime.Now;
                                                                          datePicker.CurrentlyViewedMonth =
                                                                              selectedDateForPopup.Month;
                                                                          datePicker.CurrentlyViewedYear =
                                                                              selectedDateForPopup.Year;
                                                                          datePicker.OnDateChanged(datePicker.SelectedDate, oldValue);                                                                              
                                                                          var popup = datePicker.GetTemplateChild(PartPopup) as Popup;
                                                                          if (popup != null)
                                                                              popup.IsOpen = false;
                                                                      }
                                                                  }));
   ... //a lot more not so important code here
}

Ответы [ 3 ]

2 голосов
/ 08 июня 2010

Проверьте окно вывода на наличие ошибок привязки данных.

Возможные ошибки:

  • DataContext установлен неправильно.
  • ListView ItemsSource="{Binding ElementName=this, Path=Items} Не является элементамисвойство класса Window или ViewModel?
2 голосов
/ 08 июня 2010

Убедитесь, что ваши свойства генерируют событие INotifyPropertyChanged:

public class TestClass : INotifyPropertyChanged
{
    private DateTime date;

    public DateTime Date 
    { 
        get { return date; }
        set { date = value; NotifyPropertyChanged("Date"); } 
    }

    private void NotifyPropertyChanged(string info)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }   
}

И сделайте привязку к дате также TwoWay:

<local:DatePicker SelectedDate="{Binding Date, Mode=TwoWay}"/>
0 голосов
/ 10 июня 2010

Проблема решена.

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

Спасибодля всех!

...