【问题标题】:Xamarin.Forms binding with data trigger - value not updatingXamarin.Forms 与数据触发器绑定 - 值未更新
【发布时间】:2018-01-05 13:07:51
【问题描述】:

我想在视频中显示经过的时间。我有一个带有格式说明符的标签,如下所示:

<Label Text="{Binding CurrentTime, StringFormat='{0:D3} seconds'}" />

这行得通,我得到一个像053 seconds 这样的字符串。我想在视频未播放时显示文本Not playing,我这样指定:

<Label Text="{Binding CurrentTime, StringFormat='{0:D3} seconds'}">
    <Label.Triggers>
        <DataTrigger TargetType="Label" Binding="{Binding IsPlaying}" Value="False">
            <Setter Property="Text" Value="Not playing" />
        </DataTrigger>
    </Label.Triggers>
</Label>

当视频没有播放时,这会正确显示Not playing,但是当它播放时,标签会永远停留在000 seconds。出了什么问题?

编辑

视图如下所示:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MyNamespace.VideoPage"
             x:Name="ThePage"
             BindingContext="{x:Reference Name=ThePage}">
    <StackLayout>
        <Label VerticalOptions="Center" Text="{Binding CurrentTime, StringFormat='{0:D3} seconds'}" HorizontalOptions="StartAndExpand">
            <Label.Triggers>
                <DataTrigger TargetType="Label" Binding="{Binding IsPlaying}" Value="False">
                    <Setter Property="Text" Value="Not playing" />
                </DataTrigger>
            </Label.Triggers>
        </Label>
        <!-- More stuff -->
    </StackLayout>
</ContentPage>

代码隐藏如下:

public partial class VideoPage : ContentPage
{
    private int currentTime;

    public int CurrentTime
    {
        get { return currentTime; }
        set
        {
            currentTime = value;
            OnPropertyChanged();
        }
    }

    private bool isPlaying;

    public bool IsPlaying
    {
        get { return isPlaying; }
        set
        {
            isPlaying = value;
            OnPropertyChanged();
        }
    }

    ...
}

编辑 2

在 Yuri 的回答的帮助下,我用以下方法修复了它

<ContentPage.Resources>
    <ResourceDictionary>
        <Style TargetType="Label" x:Key="PlayingStyle">
            <Setter Property="Text" Value="Not playing" />
            <Style.Triggers>
                <DataTrigger TargetType="Label" Binding="{Binding IsPlaying}" Value="True">
                    <Setter Property="Text" Value="{Binding CurrentTime, StringFormat='{0:D3} seconds'}" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ResourceDictionary>
</ContentPage.Resources>
...
<Label Style="{StaticResource PlayingStyle}" />

【问题讨论】:

  • 你绑定的类是否实现了 INotifyPropertyChanged?
  • @Jason 当我没有触发器时,值设置正确并更新。
  • 你的模型或视图模型是什么样的?
  • @Ethan2Pants 我添加了相关部分
  • 并非所有部分。我看不到“ThePage”是如何绑定的,并且 OnPropertyChanged 是如何被调用的,但是接口 INotifyPropertyChanged 是在哪里定义的?

标签: xaml xamarin data-binding xamarin.forms datatrigger


【解决方案1】:

Xaml 似乎被两种不同类型的文本绑定弄糊涂了——一种来自触发器,另一种是“直接”它是这样工作的:

   <Label VerticalOptions="Center" HorizontalOptions="StartAndExpand">
        <Label.Triggers>
            <DataTrigger TargetType="Label" Binding="{Binding  IsPlaying}"  Value="True">
                <Setter Property="Text" Value="{Binding CurrentTime, StringFormat='{0:D3} seconds'}" />
            </DataTrigger>
            <DataTrigger TargetType="Label" Binding="{Binding  IsPlaying}"  Value="False">
                <Setter Property="Text" Value="Not playing" />
            </DataTrigger>
        </Label.Triggers>
    </Label>

考虑给标签一个“默认”值的选项,并作为一个没有样式的孩子来做

    <Label VerticalOptions="Center" HorizontalOptions="StartAndExpand" Text="Not playing">
        <Label.Triggers>
            <DataTrigger TargetType="Label" Binding="{Binding  IsPlaying}"  Value="True">
                <Setter Property="Text" Value="{Binding CurrentTime, StringFormat='{0:D3} seconds'}" />
            </DataTrigger>
        </Label.Triggers>
    </Label>

【讨论】:

  • 你说对了一半。在这种情况下,您的建议很好,因为布尔值只有两个可能的值。如果它是一个数字,我希望触发值 0 并设置“其他所有内容”,那么您的解决方案将不起作用。您正确指出的我的错误是在尝试使用触发器覆盖它时直接定义该属性,这是行不通的。我已经用最终解决方案更新了我的答案。
  • 我在 Xamarin 中发现真正令人讨厌的是,我无法将这种特定样式直接定义为标签的子样式。出于某种原因,它不喜欢在其中放置触发器。它适用于 WPF 上的 Xaml。我想这只是其中一个怪癖。
  • @Steztric 使用默认设置器很好。你是对的,如果有很多选择,它会更好地工作
  • @Steztric 这个怎么样?编辑了我的答案
  • 将(甚至是空字符串)默认设置为标签实际上是一个好习惯
猜你喜欢
  • 2018-04-17
  • 1970-01-01
  • 2014-09-13
  • 1970-01-01
  • 2016-02-06
  • 1970-01-01
  • 2021-02-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多