I have the following xaml
, as you can see the DataGrid
s are being populated via DataProvider
s.
<Window x:Class="MobileDeviceAuthenticator.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MobileDeviceAuthenticator"
Title="Device Authorization" Height="381" Width="879" AllowDrop="True">
<Window.Resources>
<!-- create an instance of our DataProvider class -->
<ObjectDataProvider x:Key="MobileManagerDataProvider" ObjectType="{x:Type local:MobileManagerDataProvider}"/>
<!-- define the method which is invoked to obtain our data -->
<ObjectDataProvider x:Key="MOBILE_MANAGER" ObjectInstance="{StaticResource MobileManagerDataProvider}" MethodName="GetDevices"/>
<!-- create an instance of our DataProvider class -->
<ObjectDataProvider x:Key="MobileRequestDataProvider" ObjectType="{x:Type local:MobileRequestDataProvider}"/>
<!-- define the method which is invoked to obtain our data -->
<ObjectDataProvider x:Key="MOBILE_REQUESTS" ObjectInstance="{StaticResource MobileRequestDataProvider}" MethodName="GetDevices"/>
</Window.Resources>
<Grid Name="GridContainer" >
<Grid>
<DataGrid Name="dgAuthorization"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
DataContext="{Binding Source={StaticResource MOBILE_MANAGER}}"
ItemsSource="{Binding}"
AutoGenerateColumns="False" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=DESCRIPTION}" Header="Description" />
<DataGridTextColumn Binding="{Binding Path=DEVICE_TYPE}" Header="Device Type" IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding Path=DEVICE_ID}" Header="Device ID" IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
</Grid>
<Grid>
<DataGrid Name="dgRequest"
SelectionMode="Single"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
DataContext="{Binding Source={StaticResource MOBILE_REQUESTS}}"
ItemsSource="{Binding}"
AutoGenerateColumns="False" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=DESCRIPTION}" Header="Description" />
<DataGridTextColumn Binding="{Binding Path=DEVICE_TYPE}" Header="Device Type" IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding Path=DEVICE_ID}" Header="Device ID" IsReadOnly="True" />
<DataGridTextColumn Binding="{Binding Path=REQUEST_DATE}" Header="Request Date" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</Grid>
</Window>
Here is the DataProvider
class code
public class MobileManagerDataProvider
{
private MobileManagerDataSetTableAdapters.MOBILE_MANAGERTableAdapter mmAdapter;
private MobileManagerDataSet mmDataSet;
public MobileManagerDataProvider()
{
mmDataSet = new MobileManagerDataSet();
mmAdapter = new MobileManagerDataSetTableAdapters.MOBILE_MANAGERTableAdapter();
mmAdapter.Fill(mmDataSet.MOBILE_MANAGER);
mmDataSet.MOBILE_MANAGER.MOBILE_MANAGERRowChanged += new MobileManagerDataSet.MOBILE_MANAGERRowChangeEventHandler(AuthenticationRowModified);
mmDataSet.MOBILE_MANAGER.MOBILE_MANAGERRowDeleted += new MobileManagerDataSet.MOBILE_MANAGERRowChangeEventHandler(AuthenticationRowModified);
}
public DataView GetDevices()
{
return mmDataSet.MOBILE_MANAGER.DefaultView;
}
void AuthenticationRowModified(object sender, MobileManagerDataSet.MOBILE_MANAGERRowChangeEvent e)
{
mmAdapter.Update(mmDataSet.MOBILE_MANAGER);
}
}
In the code-behind I'd like to setup a Timer
ticking away every minute refreshing the DataGrids
.
The Timer
is easy enough, however to refresh the data is eluding me. I've tried some of the following statements.
ObjectDataProvider dataProvider = this.TryFindResource("MobileManagerDataProvider") as ObjectDataProvider;
dataProvider.Refresh();
dgAuthorization.Items.Refresh();
CollectionViewSource.GetDefaultView(dgAuthorization.ItemsSource).Refresh();
To no avail, how can I achieve this?
this is a complete working example, every time you select an item (not same item twice) it will add a new random value as a new line in the DataGrid
I've responded with an example binding new data to the DataGrid
every time you select an item in it, you can expand that case, so each time your collection changes, it will reflect in your DataGrid
automatically, so whenever your data changes you just pass to the GridData
property they will be updated in the view
MainWindow.xaml
<Window x:Class="BindingDataGrid.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:BindingDataGrid"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainViewModel />
</Window.DataContext>
<Grid>
<DataGrid ColumnWidth="*"
IsReadOnly="True"
AutoGenerateColumns="False"
SelectionMode="Single"
HorizontalContentAlignment="Center"
ItemsSource="{Binding GridData}"
SelectedItem="{Binding SelectedData, UpdateSourceTrigger=PropertyChanged}"
CanUserResizeRows="False"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto">
<DataGrid.Columns>
<DataGridTextColumn Header="Column 01" Binding="{Binding Column1}" Width="*"/>
<DataGridTextColumn Header="Column 02" Binding="{Binding Column2}" Width="*"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
MainWindow.xaml.cs Nothing here, just remove unused references
using System.Windows;
namespace BindingDataGrid //`BindingDataGrid` is my namespace
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
all references you need in your MainViewModel
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
MainViewModel
public class MainViewModel: INotifyPropertyChanged
{
Random _rnd = new Random();
private MyGridData _selectedData;
private ObservableCollection<MyGridData> _gridData;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public MainViewModel()
{
var newData = new List<MyGridData>
{
new MyGridData { Column1 = "AAAAAA 01", Column2 = "aaaaaaaa 02" },
new MyGridData { Column1 = "BBBBBB 01", Column2 = "bbbbbbbb 02" },
new MyGridData { Column1 = "CCCCCC 01", Column2 = "cccccccc 02" },
};
GridData = new ObservableCollection<MyGridData>(newData);
}
public MyGridData SelectedData
{
get { return _selectedData; }
set
{
if (value == _selectedData) //if same item selected
return;
_selectedData = value;
OnPropertyChanged();
DoSomethingWhenValueChanged(); // Will add a new line
}
}
public ObservableCollection<MyGridData> GridData
{
get { return _gridData; }
set
{
if (value == _gridData)
return;
_gridData = value;
OnPropertyChanged();
}
}
private void DoSomethingWhenValueChanged()
{
var newData = GridData.ToList();
newData.Add(new MyGridData { Column1 = (_rnd.Next(100)).ToString(), Column2 = (_rnd.Next(1000)).ToString() }); //Add new random item
GridData = new ObservableCollection<MyGridData>(newData); //update your DataGrid
}
}
public class MyGridData
{
public string Column1 { get; set; }
public string Column2 { get; set; }
}