【问题标题】:Binding doesn't work in ListView绑定在 ListView 中不起作用
【发布时间】:2011-03-01 05:07:14
【问题描述】:

我有一个名为 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
}

【问题讨论】:

  • 到底是什么问题?该日期没有显示在 datePicker 中,还是 datepicker 中的 Selected Date 没有传播到您的 TestClass 对象?在后一种情况下,您可能希望将 Mode=TwoWay 添加到您的日期选择器绑定(即 - SelectedDate="{Binding Date, Mode=TwoWay}"
  • DataPicker 中的 SelectedDate 无法访问我的 TestClass 对象,是的,Mode 到处都设置为 TwoWay
  • 你在修改 DatePicker 的源代码吗?还是您只是为了方便而发布?
  • 是的,我只是发布更多内容;我已经提到,我只是试图减少帖子中的代码量

标签: c# wpf binding controls dependency-properties


【解决方案1】:

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

【讨论】:

  • 他们抛出,当然,我只是没有在帖子中提到它以减少其中的代码大小
  • 您的类型似乎不匹配。您在控件中使用了可为空的类型,在对象中使用了不可为空的 DateTime。另外,请尝试使用普通的 PropertyMetadata 对象。我的经验是 FrameworkPropertyMetadata 对象有时会表现得相当奇怪。
【解决方案2】:

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

可能的错误:

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

【讨论】:

  • DataContext 设置正确(集合的项绑定到列表框的 ItemsSource),这只是一个简单的测试应用程序,属性是 Window 类的一部分,我认为问题确实更深层次跨度>
  • 不,我在输出窗口中没有看到数据绑定错误,这太疯狂了)
【解决方案3】:

问题解决了。

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

谢谢大家!

【讨论】:

  • 我们不都是时不时犯错吗?)
  • 是的)但我花了大约两天时间来解决这个问题,变得相当疯狂)
猜你喜欢
  • 2021-07-21
  • 2013-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-06
  • 2016-12-01
  • 2018-02-20
  • 2011-08-19
相关资源
最近更新 更多