You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UWP DataGrid列格式化问题:时长转换与收藏列交互实现

解决UWP音乐播放器的两个问题

一、修复Duration转换器找不到的问题

你的转换器无法被识别,主要有三个常见原因,我帮你逐一修正:

  1. 给转换器类添加public访问修饰符
    默认类是internal,XAML无法访问,修改代码:
public class MusicDurationConverter : Windows.UI.Xaml.Data.IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (value is string)
        {
            int seconds;
            if (int.TryParse((string)value, out seconds))
                return ToTime(seconds);
        }
        if (value is int)
            return ToTime((int)value);
        return "";
    }
    private string ToTime(int seconds)
    {
        int second = seconds % 60;
        int minute = (seconds - second) / 60;
        // 优化显示:确保秒数是两位数,比如3:05而非3:5
        return string.Format("{0}:{1:D2}", minute, second);
    }
    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return null;
    }
}
  1. 在XAML中声明转换器资源
    在你的Page/UserControl的根资源里添加转换器,别忘了引入本地命名空间:
<Page
    x:Class="你的应用命名空间.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    <!-- 替换成你的项目实际命名空间 -->
    xmlns:local="using:你的应用命名空间"
    xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls">

    <Page.Resources>
        <!-- 声明转换器,x:Key要和Binding里的名称一致 -->
        <local:MusicDurationConverter x:Key="MusicDurationConverter" />
    </Page.Resources>

    <!-- 你的DataGrid代码 -->
</Page>
  1. 修正DataGrid列的Binding写法
    你原来的写法在CellStyle里重复绑定Text且未指定Path,导致绑定对象错误。推荐直接在DataGridTextColumn的Binding里使用转换器:
<controls:DataGridTextColumn 
    MaxWidth="120" 
    Binding="{Binding Duration, Converter={StaticResource MusicDurationConverter}}" 
    Header="Duration" />

如果一定要用CellStyle,记得指定Path为Duration:

<controls:DataGridTextColumn MaxWidth="120" Header="Duration">
    <controls:DataGridTextColumn.CellStyle>
        <Style TargetType="TextBox">
            <Setter Property="Text" Value="{Binding Duration, Converter={StaticResource MusicDurationConverter}}" />
        </Style>
    </controls:DataGridTextColumn.CellStyle>
</controls:DataGridTextColumn>

二、实现收藏列的隐藏与悬停显示心形按钮

要实现隐藏"False"文本、鼠标悬停显示按钮的效果,我们需要用DataGridTemplateColumn自定义单元格内容:

1. 自定义单元格模板

假设你的数据模型有一个bool类型的IsFavorite属性,代码如下:

<controls:DataGridTemplateColumn Header="收藏">
    <controls:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <!-- 设置Grid背景为透明,确保鼠标悬停能触发整个单元格 -->
            <Grid Background="Transparent">
                <!-- 隐藏默认文本,避免显示True/False -->
                <TextBlock Text="{Binding IsFavorite}" Visibility="Collapsed" />
                
                <!-- 心形按钮:默认隐藏,鼠标悬停显示;已收藏则一直显示 -->
                <Button x:Name="FavoriteBtn"
                        Content="❤️"
                        FontSize="18"
                        Padding="4"
                        BorderThickness="0"
                        Background="Transparent"
                        <!-- 已收藏时显示按钮 -->
                        Visibility="{Binding IsFavorite, Converter={StaticResource BoolToVisibilityConverter}}">
                    <Button.Style>
                        <Style TargetType="Button">
                            <Style.Triggers>
                                <!-- 鼠标悬停时强制显示按钮 -->
                                <Trigger Property="IsMouseOver" Value="True">
                                    <Setter Property="Visibility" Value="Visible" />
                                </Trigger>
                            </Style.Triggers>
                        </Style>
                    </Button.Style>
                </Button>
            </Grid>
        </DataTemplate>
    </controls:DataGridTemplateColumn.CellTemplate>
</controls:DataGridTemplateColumn>

2. 添加Bool转Visibility的转换器

上面用到了BoolToVisibilityConverter,新建这个转换器类:

public class BoolToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return value is bool isFavorite && isFavorite ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

别忘了在Page.Resources里声明这个转换器:

<local:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />

3. 按钮点击事件(可选)

如果需要点击按钮切换收藏状态,在后台添加点击事件:

private void FavoriteBtn_Click(object sender, RoutedEventArgs e)
{
    var button = sender as Button;
    var musicItem = button.DataContext as YourMusicModel; // 替换成你的数据模型类
    if (musicItem != null)
    {
        musicItem.IsFavorite = !musicItem.IsFavorite;
        // 这里可以添加收藏状态保存到本地的逻辑
    }
}

这样设置后,未收藏的单元格默认是空的,鼠标悬停时显示心形按钮;已收藏的单元格会一直显示心形按钮,完美符合你的需求~

内容的提问来源于stack exchange,提问作者user10634280

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:54:44