【问题标题】:Data binding inside ProgressBar value not working for DataGridTemplateColumnProgressBar 值内的数据绑定不适用于 DataGridTemplateColumn
【发布时间】:2020-01-19 15:12:21
【问题描述】:

我的问题是我试图在 DataGridTemplateColumn 内显示 ProgressBar 值,并且绑定不想工作。它适用于我的 TextBlock(在同一个网格中),但不适用于 ProgressBar。

我已经参考了许多参考资料(Microsoft 和 StackOverFlow)来尝试找到我的解决方案。但是,它们都没有真正帮助解决我使用此绑定的解决方案。 主要有用的例子: Progress Bar Bind Value , https://www.wpf-tutorial.com/misc-controls/the-progressbar-control/ , WPF how to display text on progress bar

另外,我最初将 PercentFull 传递给一个 double 值(我认为这不起作用),所以我将它传递给一个 Int 值。但是,无论哪种方式,绑定都不想合作。

XAML

<DataGrid x:Name="dgViewData2" Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" Grid.RowSpan="3" Background="Transparent" Foreground="White" AutoGenerateColumns="False"
    FontSize="18" FontWeight="Medium" BorderThickness="0" HorizontalGridLinesBrush="White" VerticalGridLinesBrush="White" Margin="10" IsHitTestVisible="False" CanUserAddRows="False"
    ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Auto" HeadersVisibility="Column" Visibility="Collapsed"
    GridLinesVisibility="All" CanUserSortColumns="False" IsReadOnly="True">
    <DataGrid.Resources>
        <Style TargetType="DataGrid">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="Focusable" Value="False"/>
            <Setter Property="IsHitTestVisible" Value="True"/>
        </Style>
        <Style TargetType="DataGridColumnHeader">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="Focusable" Value="False"/>
            <Setter Property="HorizontalAlignment" Value="Right"/>
            <Setter Property="FontWeight" Value="Bold"/>
            <Setter Property="FontSize" Value="20"/>
        </Style>
        <Style TargetType="DataGridRow">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="Focusable" Value="False"/>
            <Setter Property="HorizontalAlignment" Value="Right"/>
        </Style>
        <Style TargetType="DataGridCell">
            <Setter Property="HorizontalAlignment" Value="Right"/>
            <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="Background" Value="{x:Null}"/>
                <Setter Property="BorderBrush" Value="{x:Null}"/>
                <Setter Property="Foreground" Value="Transparent"/>
            </Trigger>
        </Style.Triggers>
        </Style>
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTextColumn Width="150"  Binding="{Binding Identifyer}"/>
        <DataGridTextColumn Width="*"  Binding="{Binding Denomination}"/>
        <DataGridTextColumn Width="*"  Binding="{Binding Quantity}"/>
        <DataGridTextColumn Width="*" Binding="{Binding MaxQuantity}"/>
        <DataGridTextColumn Width="*"  Binding="{Binding TotalValue}"/>
        <!--<DataGridTextColumn Width="*" Binding="{Binding PercentFull}"/>-->
        <DataGridTemplateColumn Width="200" Visibility="Visible">
        <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Grid>
                <ProgressBar Name="pbCash" Width="200" Minimum="{Binding Path=PercentFullMin}" Maximum="{Binding Path=PercentFullMax}" Value="{Binding Path=PercentFull}" Background="Transparent" Foreground="DarkGreen" IsIndeterminate="False"/>
                <TextBlock x:Name="tbProgress" Text="{Binding Path=PercentFullText, StringFormat={}{0}%}"  HorizontalAlignment="Center" VerticalAlignment="Center" Background="Transparent" Foreground="White"/>
            </Grid>
        </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

C#

public List<Recycler_Data> items2 { get; set; } = new List<Recycler_Data>(); //This is being set at the very top of the class.


foreach (var r in data.Recyclers)
{
    foreach (var c in r.Contents)
    {
        //Inserting Column Headers
        dgViewData2.Columns[0].Header = $"{item.Name}";
        dgViewData2.Columns[1].Header = "Value";
        dgViewData2.Columns[2].Header = "Qty";
        dgViewData2.Columns[3].Header = "Max Qty";
        dgViewData2.Columns[4].Header = "Total";
        dgViewData2.Columns[5].Header = "Full";
        string pfTxt = Convert.ToString((Convert.ToDouble(c.Quantity) / Convert.ToDouble(data.Capacity) * 100).ToString("0.00"));
        items2.Add(new Recycler_Data()
        {
            Identifyer = r.Identifyer,
            Denomination = c.Denomination.ToString().Remove(0, 3).Insert(0, " $"),
            Quantity = c.Quantity,
            MaxQuantity = item.Capacity,
            TotalValue = r.TotalValue.ToString().Remove(0, 3).Insert(0, " $"),
            PercentFullText = pfTxt,
            PercentFull = (Convert.ToInt32(c.Quantity) / Convert.ToInt32(data.Capacity) * 100),
            PercentFullMax = 100, 
            PercentFullMin = 0
        });
    }
}
dgViewData2.ItemSource = items2;
public class Recycler_Data
{
    public string Identifyer { get; set; }
    public string Denomination { get; set; }
    public long Quantity { get; set; }
    public object MaxQuantity { get; set; }
    public string TotalValue { get; set; }
    public string PercentFullText { get; set; }
    public int PercentFull { get; set; }
    public int PercentFullMax { get; set; }
    public int PercentFullMin { get; set; }
}

所以我期望进度条显示通过 PercentFull 的任何数字(显然在 0 到 100 之间)。

【问题讨论】:

  • Recycler_Data 需要实现 INotifyPropertyChanged。 PercentFull 需要引发 PropertyChanged 事件,在事件 args 中传递自己的名称 nameof(PercentFull),当其值发生变化时。也就是说,如果问题是您在加载进度条后更改PercentFull 的值,并且您希望看到进度条的值发生变化。从您的问题中不清楚PercentFull 在初始化后是否会发生变化。
  • 你发现的两个 SO 问题运气不好。此外,很少有 WPF 教程是由了解 WPF 的任何人编写的。我通常将人们引向 Rachel Lim 的网站。绑定到 ProgressBar 的属性与绑定到大多数其他属性没有什么不同,所以您真正需要的是绑定教程,而不是进度条教程。

标签: c# wpf xaml data-binding


【解决方案1】:

这里看起来像一个整数舍入问题:

public int PercentFull { get; set;}
PercentFull = (Convert.ToInt32(c.Quantity) / Convert.ToInt32(data.Capacity) * 100);

假设 c.Quantity 为 2,data.Capacity 为 60。这将说 2/60,即 0,因为数学是作为 int 完成的,并且整数数学默认向下舍入。最后,0 * 100 = 0 就是你的结果。

您可以使用双打来修复它:

public double PercentFull {get; set;}
PercentFull = c.Quantity / Convert.ToDouble(data.Capacity) * 100;

如果要保留整数类型:(精度会降低)

public int PercentFull {get; set;}
PercentFull = Convert.ToInt32(c.Quantity) * 100 / Convert.ToInt32(data.Capacity);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-28
    • 2011-11-27
    • 2017-02-28
    • 1970-01-01
    • 1970-01-01
    • 2018-06-01
    • 2017-07-13
    • 2019-09-21
    相关资源
    最近更新 更多