C#(WP8.1)中的数据绑定,同时设置stackpanel的datacontext不起作用

时间:2015-06-06 08:18:53

标签: c# xaml windows-phone-8 data-binding

不起作用的代码:

<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 class - &gt;

的一部分
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类 - &gt;

public class TimeSnap
{
    public TimeSpan LapTime { get; set; }
    public TimeSpan SplitTime { get; set; }
}

两个xaml代码之间的区别在于,在第一个代码中,我将DataContextStackPanel的{​​{1}}设置为DataTemplate,然后简单地使用名称堆栈面板内SplitTime内的属性(例如TextBlocks)。

在第二个xaml代码中,我没有设置Hours的任何DataContext,在文本框中我使用了文本块绑定中的完整路径(例如StackPanel)。

第二种方法有效但我需要它以第一种方式工作。据我所知,这两种方法应该意味着相同的绑定路径。但在第一种方法中,我得到以下绑定错误:

  

错误:BindingExpression路径错误:&#39;小时&#39;找不到&{39; SplitTime.Hours&#39;。 BindingExpression:Path =&#39; Hours&#39;的DataItem =&#39; Windows.Foundation.IReference`1&#39 ;;目标元素是&#39; Windows.UI.Xaml.Controls.TextBlock&#39; (名称=&#39;空&#39);目标属性是&#39; Text&#39; (键入&#39; String&#39;)

     

错误:BindingExpression路径错误:&#39;分钟&#39;找不到&{39; Windows.Foundation.IReference`1<String>&#39;。 BindingExpression:Path =&#39; Minutes&#39;的DataItem =&#39; Windows.Foundation.IReference`1&#39 ;;目标元素是&#39; Windows.UI.Xaml.Controls.TextBlock&#39; (名称=&#39;空&#39);目标属性是&#39; Text&#39; (键入&#39; String&#39;)

     

错误:BindingExpression路径错误:&#39;秒&#39;找不到&{39; Windows.Foundation.IReference`1<String>&#39;。 BindingExpression:Path =&#39; Seconds&#39;的DataItem =&#39; Windows.Foundation.IReference`1&#39 ;;目标元素是&#39; Windows.UI.Xaml.Controls.TextBlock&#39; (名称=&#39;空&#39);目标属性是&#39; Text&#39; (键入&#39; String&#39;)

     

错误:BindingExpression路径错误:&#39;毫秒&#39;找不到&{39; Windows.Foundation.IReference`1<String>&#39;。 BindingExpression:Path =&#39;毫秒&#39;的DataItem =&#39; Windows.Foundation.IReference`1&#39 ;;目标元素是&#39; Windows.UI.Xaml.Controls.TextBlock&#39; (名称=&#39;空&#39);目标属性是&#39; Text&#39; (键入&#39; String&#39;)

2 个答案:

答案 0 :(得分:0)

绑定到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继承数据。 对于每个TextBox,您应该使用:

<TextBlock Text="{Binding SplitTime, Converter={StaticResource TimeSecondConverter}}" 
                               FontSize="30"></TextBlock>

” 并使用不同的转换器来显示秒,分钟等。

答案 1 :(得分:0)

我终于通过为TimeSpan创建一个包装类来解决它。我相信TimeSpan是一个结构是问题所在。不过我不确定。 无论如何,我添加了以下类 - &gt;

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代码正常工作。