UWP DataGrid列格式化问题:时长转换与收藏列交互实现
解决UWP音乐播放器的两个问题
一、修复Duration转换器找不到的问题
你的转换器无法被识别,主要有三个常见原因,我帮你逐一修正:
- 给转换器类添加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; } }
- 在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>
- 修正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
相关产品推荐
相关产品推荐

