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内的StackPanelDataContext设置为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")

c# (WP8.1)中的数据绑定在设置stackpanel的数据上下文时不起作用

绑定到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代码工作了