1

I have a working ProgressBar displayed in a single column. But need it instead to span over the whole row. How can that be achieved?

This works, ProgressBar in single column :

 <UserControl.Resources>
        <SolidColorBrush x:Key="DgGridLineBrush" Color="LightGray"  />

        <Style x:Key="ProgressBarStyle" TargetType="ProgressBar">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ProgressBar">
                        <Grid x:Name="PART_Track" >
                            <Rectangle x:Name="PART_Indicator" Fill="{Binding [3]}" HorizontalAlignment="Left" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>

<DataGrid x:Name="MbpDg"  HeadersVisibility="Column" AutoGenerateColumns="False" IsReadOnly="True" CanUserAddRows="False" HorizontalAlignment="Right" ColumnHeaderHeight="20" Height="221" Margin="0,1,0,0" VerticalAlignment="Top" Width="164"
      GridLinesVisibility="None" >
<DataGrid.Columns>
    <DataGridTemplateColumn Header="Size" Width="55"> 
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <Grid>
                   <ProgressBar Value="{Binding [2], Mode=OneWay}" Style="{StaticResource ProgressBarStyle}" Minimum="0" Maximum="100"/>
                   <TextBlock Text="{Binding [2], Mode=OneWay}" HorizontalAlignment="Right"/>
                </Grid>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
    <DataGridTextColumn Binding="{Binding [0]}" Header="Price" Width="50"/>
    <DataGridTextColumn Binding="{Binding [1]}" Header="Qty" Width="30*"/>
</DataGrid.Columns> 

I did see this question, but attempting to incorporate it gives binding exceptions.. I don't really know what I'm doing here to be honest..

 <Setter Property="DataGrid.Template">
 <Setter.Value>
     <ControlTemplate TargetType="{x:Type DataGridRow}">
         <Grid>
             <ProgressBar Value="{Binding [2], Mode=OneWay}"  Style="{StaticResource ProgressBarStyle}" Minimum="0" Maximum="100"/>
         </Grid>
     </ControlTemplate>
 </Setter.Value>

EDIT: Answer worked great, but left with this "error" displayed three times:

System.Windows.Data Error: 1 : Cannot create default converter to perform 'one-way' conversions between types 'System.Boolean' and 'System.Windows.Controls.SelectiveScrollingOrientation'. Consider using Converter property of Binding. BindingExpression:Path=AreRowDetailsFrozen; DataItem='DataGrid' (Name='MyDg'); target element is 'DataGridDetailsPresenter' (Name=''); target property is 'SelectiveScrollingOrientation' (type 'SelectiveScrollingOrientation')
System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='False' BindingExpression:Path=AreRowDetailsFrozen; DataItem='DataGrid' (Name='MyDg'); target element is 'DataGridDetailsPresenter' (Name=''); target property is 'SelectiveScrollingOrientation' (type 'SelectiveScrollingOrientation')
bretddog
  • 5,411
  • 11
  • 63
  • 111

1 Answers1

3

You'll have to template the DataGridRow. First, add a temporary DataGridRow as a child of your DataGrid, place your cursor on that element and then in the properties window go to Miscellaneous -> Template, click on the little square to the right of it and select "Convert To New Resource". That will create a new DataGridRow template in your resources block which you can then set with a style. (For some reason it also makes the row headers appear on my machine, so either delete it from the template or just set `RowHeaderWidth='0' on your DataGrid).

As far as making your progress bar visible, just add it as the first child of the SelectiveScrollingGrid in the template (if you haven't deleted the first column then you'll also need to set it's Grid.Column to 1).

Put this all together and your DataGrid declaration will look something like this (I've added an ItemsSource binding which you'll probably want to remove):

<DataGrid x:Name="MbpDg" ItemsSource="{Binding Items}"  HeadersVisibility="Column" AutoGenerateColumns="False" IsReadOnly="True" CanUserAddRows="False" HorizontalAlignment="Left" ColumnHeaderHeight="20" Height="221" Margin="0,1,0,0" VerticalAlignment="Top" Width="164" CanUserResizeRows="False" GridLinesVisibility="None">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding [2]}" Header="Size" Width="50"/>
        <DataGridTextColumn Binding="{Binding [0]}" Header="Price" Width="50"/>
        <DataGridTextColumn Binding="{Binding [1]}" Header="Qty" Width="30*"/>
    </DataGrid.Columns>
</DataGrid>

Set the style in your resources block:

<Style TargetType="{x:Type DataGridRow}">
    <Setter Property="Template" Value="{DynamicResource DataGridRowControlTemplate1}" />
</Style>

And here's the template itself:

<ControlTemplate x:Key="DataGridRowControlTemplate1" TargetType="{x:Type DataGridRow}">
    <Border x:Name="DGR_Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
        <SelectiveScrollingGrid SelectiveScrollingOrientation="None">
            <SelectiveScrollingGrid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
            </SelectiveScrollingGrid.RowDefinitions>
            <ProgressBar HorizontalAlignment="Stretch" Value="{Binding [2]}" Minimum="0" Maximum="100"/>
            <DataGridCellsPresenter ItemsPanel="{TemplateBinding ItemsPanel}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
            <DataGridDetailsPresenter Grid.Row="1" Visibility="{TemplateBinding DetailsVisibility}" />
        </SelectiveScrollingGrid>
    </Border>
</ControlTemplate>

Result:

enter image description here

Mark Feldman
  • 15,731
  • 3
  • 31
  • 58
  • Excellent! Though I'm left with a "System.Windows.Data Error" (See edit). Is that something that can/should be addressed? – bretddog Jun 02 '19 at 08:43
  • If I'm not mistaken then you don't need cells to scroll, in which case I think you can just delete that entire section of XAML and set `SelectiveScrollingOrientation="None"` explicitly in the `SelectiveScrollingGrid` (you can always change it to something else later if you need to). I've updated my code accordingly. – Mark Feldman Jun 02 '19 at 10:51