绑定在ListView中不起作用

时间:2010-06-08 14:42:13

标签: c# wpf binding controls dependency-properties

我有一个名为DataPicker的wpf控件,它有一个名为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 个答案:

答案 0 :(得分:2)

确保您的属性抛出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}"/>

答案 1 :(得分:2)

检查输出窗口是否有任何数据绑定错误..

可能的错误:

  • 未正确设置DataContext。
  • ListView ItemsSource="{Binding ElementName=this, Path=Items}项目不是Window或ViewModel类的属性吗?

答案 2 :(得分:0)

问题解决了。

它不是错误的绑定或其他困难和不平衡的东西,但是,因为它是遗留代码,代码程序员的某个地方犯了一个错误。

感谢所有人!