I am new to .Net and I want to know how I can update the progress bar when I click on the Download Button in a particular row on the DataGrid. Since there's limited sources that address this I don't understand how to achieve this.
<DataGrid AutoGenerateColumns="False" x:Name="servers" HorizontalAlignment="Center" Height="148" Margin="0,78,0,0" VerticalAlignment="Top" Width="772" PreviewMouseDoubleClick="clientPreview" >
<DataGrid.Columns>
<DataGridTextColumn Header="ID" IsReadOnly="True" Binding="{Binding Id}" Width="50"></DataGridTextColumn>
<DataGridTemplateColumn Header="Progress"
Width="100">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ProgressBar
Value="{Binding Progress}"
Minimum="0" Maximum="100" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Action" Width="100">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate >
<Button Background="#FF00FF35" Click="beginDownload">Download</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
The Generated DataGrid Looks like this :
The BeginDownload Method Looks like this :
private void beginDownload(object sender, RoutedEventArgs e)
{
Clients selected = servers.SelectedItem as Clients;
if (selected != null)
{
if (selected.Id == 0)
{
MessageBox.Show("Selected Feild is Empty", Title = "Empty Feild Selected");
}
else
{
//Update Progess Bar and Other Methods
}
}
else
{
MessageBox.Show("Selected Field is Empty", Title = "Empty Field Selected");
}
}
I only want to know how I can update the progess bar in a particular row. For example if I put a for loop and update the progress from 0 to 100. How to bind the integer value to the progress bar?
Found a Similar problem with no answers -Wpf Datagrid change element in the same row on click
CodePudding user response:
My Solution in Page.xaml.cs:
Visual vis;
private void beginDownload(object sender, RoutedEventArgs e)
{
Clients selected = servers.SelectedItem as Clients;
if (selected != null)
{
if (selected.Id == 0)
{
MessageBox.Show("Selected Feild is Empty", Title = "Empty Feild Selected");
}
else
{
for (vis = sender as Visual; vis != null; vis = VisualTreeHelper.GetParent(vis) as Visual)
if (vis is DataGridRow) //Find current DataGridRow
{
ProgressChanged();
//Other methods
break;
}
}
}
else
{
MessageBox.Show("Selected Field is Empty", Title = "Empty Field Selected");
}
}
private void ProgressChanged()
{
// Update the progressbar percentage
for (int i = 0; i <= 100; i )
{
((Clients)(((DataGridRow)vis).Item)).Progress = i;
}
}
My Clients Class :
public class Clients : INotifyPropertyChanged
{
private int mProgress;
public Clients()
{
Id = 0;
}
public int Id { get; set; }
public int Progress
{
get { return mProgress; }
set
{
mProgress = value;
OnPropertyChanged("Progress");
}
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
I have one more issue my progress bar speed is too fast, How can I slow down the progress bar speed?
CodePudding user response:
In the WPF very popular MVVM approach with command pattern. Accordingly to it.. you need to have View and ViewModel.. then you will be able to use command for the Download button in your grid and pass parameter to it.
public class ClientsViewModel : INotifyPropertyChanged
{
public DelegateCommand DownloadCommand {get; private set;}
// ctor
public ClientsVM()
{
DownloadCommand = new DelegateCommand(DownloadExecute));
}
// async method allow to not block UI thread
public async void DownloadExecute(object param)
{
var client = param as Clients;
if (client==null) return;
// TODO: call real code for download
for (int i=0; i<100; i )
{
await Task.Delay(100); // slow changes of progress
client.Progress = i; // if setter of Progress raised NotifyPropertyChanged.. it will update ProgressBar in your DataGrid
}
}
}
For use your DownloadCommand just bind it to the property of Button
<DataGrid AutoGenerateColumns="False" x:Name="servers" HorizontalAlignment="Center" Height="148" Margin="0,78,0,0" VerticalAlignment="Top" Width="772" PreviewMouseDoubleClick="clientPreview">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" IsReadOnly="True" Binding="{Binding Id}" Width="50"></DataGridTextColumn>
<DataGridTemplateColumn Header="Progress"
Width="100">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ProgressBar
Value="{Binding Progress}"
Minimum="0" Maximum="100" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Action" Width="100">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate >
<Button Background="#FF00FF35" Command="{Binding DownloadCommand, Mode=OneWay}" CommandParameter="{Binding}">Download</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>