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

WPF C#:如何单独控制DataGrid每行的ProgressBar

如何单独控制DataGrid中每行的ProgressBar?

问题根源分析

你的核心问题出在数据模型设计和绑定逻辑上:

  1. 当前ViewModel里的PercentageOfFrame是单个全局属性,而DataGrid每行需要独立的进度值,共用一个属性必然导致所有进度条同步变化。
  2. XAML中ProgressBar的绑定错误:用RelativeSource指向DataGridRow,但Row的DataContext是数组中的字符串,根本没有PercentageOfFrame属性,绑定自然失效。
  3. 后台直接操作UI元素的方式错误:dg.FindName("progressbar")找不到行模板内的ProgressBar,因为每个行模板的控件都是独立实例,不属于DataGrid的命名空间。

解决方案步骤

1. 创建行数据实体类

每个DataGrid行对应一个独立的实体,包含自身的进度属性:

public class CmdLine : INotifyPropertyChanged
{
    private string _commandText;
    private int _percentage;

    public string CommandText
    {
        get => _commandText;
        set
        {
            _commandText = value;
            NotifyPropertyChanged(nameof(CommandText));
        }
    }

    public int Percentage
    {
        get => _percentage;
        set
        {
            _percentage = value;
            NotifyPropertyChanged(nameof(Percentage));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

2. 修改ViewModel,使用ObservableCollection存储行数据

替换原有的字符串数组,改用支持变更通知的集合类型:

public class CMD_VM : INotifyPropertyChanged
{
    private ObservableCollection<CmdLine> _cmdLines;
    private int _numberOfFrame;

    public ObservableCollection<CmdLine> CmdLines
    {
        get => _cmdLines;
        set
        {
            _cmdLines = value;
            NotifyPropertyChanged(nameof(CmdLines));
        }
    }
    
    public int NumberOfFrame
    {
        get => _numberOfFrame;
        set
        {
            _numberOfFrame = value;
            NotifyPropertyChanged(nameof(NumberOfFrame));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public CMD_VM()
    {
        CmdLines = new ObservableCollection<CmdLine>();
        // 初始化时可填充命令数据,示例:
        // CmdLines.Add(new CmdLine { CommandText = "执行命令1", Percentage = 0 });
    }
}

3. 修正XAML绑定

让ProgressBar直接绑定到当前行实体的Percentage属性:

<DataGrid x:Name="Datagrid_CmdLines" SelectionUnit="Cell" HeadersVisibility="None" 
          ItemsSource="{Binding CmdLines}" Margin="52,308,0,0" AutoGenerateColumns="False" 
          Width="635" Height="393" HorizontalAlignment="Left" VerticalAlignment="Top" 
          Background="#FFEEEEEE" Grid.Row="1">
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
            <Setter Property="IsHitTestVisible" Value="False"/>
        </Style>
    </DataGrid.RowStyle>
    <DataGrid.Columns>
        <!-- 命令文本列 -->
        <DataGridTextColumn Width="*" Binding="{Binding CommandText}"/>
        <!-- 进度条列 -->
        <DataGridTemplateColumn Width="150">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ProgressBar Value="{Binding Percentage}" Minimum="0" Maximum="100" Height="20"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

4. 修改后台控制逻辑

通过ViewModel中的数据实体更新进度,而非直接操作UI:

private void ColorRow(System.Windows.Controls.DataGrid dg)
{
    // 校验索引有效性
    if (cmdvm.NumberOfFrame <= 0 || cmdvm.NumberOfFrame > cmdvm.CmdLines.Count)
        return;

    // 获取目标行的实体对象
    var targetCmdLine = cmdvm.CmdLines[cmdvm.NumberOfFrame - 1];
    // 更新该行的进度值
    targetCmdLine.Percentage = registers[61];

    // 可选:设置行背景色
    DataGridRow row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(cmdvm.NumberOfFrame - 1);
    if (row != null)
    {
        row.Background = brush;
    }
}

关键要点

  • 每个行对应独立的数据实体,确保进度值互不干扰
  • 使用ObservableCollection代替数组,自动同步集合变更到UI
  • 遵循MVVM模式,通过修改数据属性更新UI,避免直接操作控件
  • 修正绑定路径,让控件直接绑定到行数据的对应属性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 15:24:55