c# (WP8.1)中的数据绑定在设置stackpanel的数据上下文时不起作用
本文关键字:stackpanel 设置 数据 上下文 不起作用 数据绑定 WP8 | 更新日期: 2023-09-27 17:53:57
不能运行的代码:
<ListView x:Name="list_lapTimes"
ScrollViewer.VerticalScrollMode="Auto"
Grid.Row="1"
ItemsSource="{Binding RecTimes}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal"
Grid.Column="0"
HorizontalAlignment="Center"
DataContext="SplitTime">
<TextBlock Text="{Binding Hours, Converter={StaticResource TimeConverter}}"
FontSize="30"></TextBlock>
<TextBlock FontSize="30">:</TextBlock>
<TextBlock Text="{Binding Minutes, Converter={StaticResource TimeConverter}}"
FontSize="30"></TextBlock>
<TextBlock FontSize="30">:</TextBlock>
<TextBlock Text="{Binding Seconds, Converter={StaticResource TimeConverter}}"
FontSize="30"></TextBlock>
<TextBlock FontSize="15" VerticalAlignment="Bottom">.</TextBlock>
<TextBlock Text="{Binding Milliseconds, Converter={StaticResource TimeConverter}, ConverterParameter=something}"
FontSize="15"
VerticalAlignment="Bottom"></TextBlock>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
有效的代码:
<ListView x:Name="list_lapTimes"
ScrollViewer.VerticalScrollMode="Auto"
Grid.Row="1"
ItemsSource="{Binding RecTimes}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal"
Grid.Column="0"
HorizontalAlignment="Center">
<TextBlock Text="{Binding SplitTime.Hours, Converter={StaticResource TimeConverter}}"
FontSize="30"></TextBlock>
<TextBlock FontSize="30">:</TextBlock>
<TextBlock Text="{Binding SplitTime.Minutes, Converter={StaticResource TimeConverter}}"
FontSize="30"></TextBlock>
<TextBlock FontSize="30">:</TextBlock>
<TextBlock Text="{Binding SplitTime.Seconds, Converter={StaticResource TimeConverter}}"
FontSize="30"></TextBlock>
<TextBlock FontSize="15" VerticalAlignment="Bottom">.</TextBlock>
<TextBlock Text="{Binding SplitTime.Milliseconds, Converter={StaticResource TimeConverter}, ConverterParameter=something}"
FontSize="15"
VerticalAlignment="Bottom"></TextBlock>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
下面是Page类的一部分——>
public ObservableCollection<TimeSnap> RecTimes { get; set; }
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
sw = new Stopwatch(Dispatcher);
RecTimes = new ObservableCollection<TimeSnap>();
DataContext = this;
}
这里是TimeSnap类——>
public class TimeSnap
{
public TimeSpan LapTime { get; set; }
public TimeSpan SplitTime { get; set; }
}
两个xaml代码之间的区别在于,在第一个代码中,我将DataTemplate
内的StackPanel
的DataContext
设置为SplitTime
,然后简单地使用stackpanel内TextBlocks
中的属性名称(例如Hours
)。
在第二个xaml代码中,我没有设置StackPanel
的任何DataContext
,并且在文本框中,我使用了文本块绑定中的完整路径(例如SplitTime.Hours
)。
第二种方法可以工作,但是,我需要它以第一种方式工作。据我所知,这两种方法应该意味着相同的绑定路径。但是在第一种方法中,我得到了以下绑定错误:
错误:BindingExpression路径错误:'Hours'属性在'
Windows.Foundation.IReference`1<String>
'上找不到。BindingExpression: Path='Hours' DataItem='Windows.Foundation.IReference ' 1';目标元素是"Windows.UI.Xaml.Controls"。TextBlock"(Name =‘零’);目标属性为"Text"(类型为"String")错误:BindingExpression路径错误:'Minutes'属性在'
Windows.Foundation.IReference`1<String>
'上找不到。BindingExpression: Path='Minutes' DataItem='Windows.Foundation.IReference ' 1';目标元素是"Windows.UI.Xaml.Controls"。TextBlock"(Name =‘零’);目标属性为"Text"(类型为"String")错误:BindingExpression路径错误:'Seconds'属性在'
Windows.Foundation.IReference`1<String>
'上找不到。BindingExpression: Path='Seconds' DataItem='Windows.Foundation.IReference ' 1';目标元素是"Windows.UI.Xaml.Controls"。TextBlock"(Name =‘零’);目标属性为"Text"(类型为"String")错误:BindingExpression路径错误:'Milliseconds'属性在'
Windows.Foundation.IReference`1<String>
'上找不到。BindingExpression: Path='Milliseconds' DataItem='Windows.Foundation.IReference ' 1';目标元素是"Windows.UI.Xaml.Controls"。TextBlock"(Name =‘零’);目标属性为"Text"(类型为"String")
绑定到DataContext
时必须使用相同的语法:
<StackPanel Orientation="Horizontal"
Grid.Column="0"
HorizontalAlignment="Center"
DataContext="{Binding SplitTime}">
你剩下的代码看起来不错。
如果您将模型绑定到Page.DataContext
,我建议使用:
<StackPanel Orientation="Horizontal"
Grid.Column="0"
HorizontalAlignment="Center"
DataContext="{Binding DataContext.SplitTime, ElementName=list_lapTimes}">
更新2 StackPanel不需要任何DataContext绑定,因为它会自动从ListView继承数据。对于每个文本框,你应该使用:
<TextBlock Text="{Binding SplitTime, Converter={StaticResource TimeSecondConverter}}"
FontSize="30"></TextBlock>
'并使用不同的转换器显示秒,分等
我最终通过为TimeSpan创建一个包装器类来解决这个问题。我认为TimeSpan是一个结构体是问题所在。然而,我不确定。总之,我添加了下面的类——>
public class TimeSpanCustom
{
TimeSpan ts;
public int Hours { get; set; }
public int Minutes { get; set; }
public int Seconds { get; set; }
public int Milliseconds { get; set; }
public TimeSpanCustom(int days, int hours, int minutes, int seconds, int milliseconds)
{
this.Hours = hours;
this.Minutes = minutes;
this.Seconds = seconds;
this.Milliseconds = milliseconds;
ts = new TimeSpan(days, hours, minutes, seconds, milliseconds);
}
public TimeSpanCustom Subtract(TimeSpanCustom ts)
{
TimeSpan minuend = new TimeSpan(0, ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);
TimeSpan result = this.ts.Subtract(minuend);
return new TimeSpanCustom(0, result.Hours, result.Minutes, result.Seconds, result.Milliseconds);
}
}
并将TimeSnap类改为使用TimeSpanCustom而不是TimeSpan。
public class TimeSnap
{
public TimeSpanCustom LapTime { get; set; }
public TimeSpanCustom SplitTime { get; set; }
}
现在第一个xaml代码工作了