绑定在 ListView 中不起作用
我有一个名为 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
}
I have a wpf control named DataPicker which has a dependency property named SelectedDate.
In simple cases it works well but there is one case where binding fails and I can't understand why: when i try to bind it inside a ListView.
For example, I have class (INotifyPropertyChanged is implemented)
public class TestClass : INotifyPropertyChanged
{
public string Name { get; set; }
public DateTime Date { get; set; }
}
and try to bind sample collection like
public ObservableCollection<TestClass> Items { get; set; }
which has one element in it.
Binding looks like
<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>
and Name property works fine.
inside my DatePicker date value is shown this way:
<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>
any ideas why this could happen?
More code of the DatePicker class: (some specific properties that I need I'll rather miss to keep code size not so large)
[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
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
检查输出窗口是否有任何数据绑定错误。
可能的错误:
ListView ItemsSource="{Binding ElementName=this, Path=Items}
Items 不是 Window 或 ViewModel 类的属性吗?Check the output window for any data binding errors..
Probable errors:
ListView ItemsSource="{Binding ElementName=this, Path=Items}
Isn't Items a property of the Window or a ViewModel class ?问题解决了。
它不是错误的绑定或其他困难和不均匀的东西,但是,由于它是遗留代码,代码程序员在代码中的某个地方犯了错误。
谢谢大家!
The problem is solved.
It was not in wrong bindings or other difficult and uneven stuff, but, as it was legacy code, somewhere in code programmer made a mistake.
Thank for all!
确保您的属性抛出 INotifyPropertyChanged 事件:
并使您的日期绑定也为 TwoWay:
Make sure your properties throw the INotifyPropertyChanged event:
And make your binding to the date also TwoWay: