I am developing an application using WPF MVVM.
My program needs to quickly update a lot of data and display it in the UI.
I have a function that reads 2000 data from shared memory every 1millisecond and updates the UI.
At this time, there is a phenomenon that the data update is temporarily stopped every 2-3 seconds.
There was no stopping when updating from code behind without using MVVM.
To improve this phenomenon, the update cycle was changed to 100 milliseconds, but the freeze did not improve.
If you have experienced something like this, please share your solution with me.
The source code is a sample of the problem from my product.
Thank you very much.
View
<UserControl x:Class="BindingHang.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BindingHang.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<Style TargetType="ListView">
<Setter Property="IsSynchronizedWithCurrentItem" Value="True" />
<Setter Property="Margin" Value="5" />
</Style>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ListView Grid.Row="0" Grid.Column="0" ItemsSource="{Binding Path=Changes1}">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn DisplayMemberBinding="{Binding Path=Name}" Header="Name" />
<GridViewColumn DisplayMemberBinding="{Binding Path=Value}" Header="Value" Width="100" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
<ListView Grid.Row="0" Grid.Column="1" ItemsSource="{Binding Path=Changes2}">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn DisplayMemberBinding="{Binding Path=Name}" Header="Name" />
<GridViewColumn DisplayMemberBinding="{Binding Path=Value}" Header="Value" Width="100" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
<ListView Grid.Row="0" Grid.Column="2" ItemsSource="{Binding Path=Changes3}">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn DisplayMemberBinding="{Binding Path=Name}" Header="Name" />
<GridViewColumn DisplayMemberBinding="{Binding Path=Value}" Header="Value" Width="100" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
<ListView Grid.Row="0" Grid.Column="3" ItemsSource="{Binding Path=Changes4}">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn DisplayMemberBinding="{Binding Path=Name}" Header="Name" />
<GridViewColumn DisplayMemberBinding="{Binding Path=Value}" Header="Value" Width="100" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
<ListView Grid.Row="1" Grid.Column="0" ItemsSource="{Binding Path=Changes5}">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn DisplayMemberBinding="{Binding Path=Name}" Header="Name" />
<GridViewColumn DisplayMemberBinding="{Binding Path=Value}" Header="Value" Width="100" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
<ListView Grid.Row="1" Grid.Column="1" ItemsSource="{Binding Path=Changes6}">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn DisplayMemberBinding="{Binding Path=Name}" Header="Name" />
<GridViewColumn DisplayMemberBinding="{Binding Path=Value}" Header="Value" Width="100" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
<ListView Grid.Row="1" Grid.Column="2" ItemsSource="{Binding Path=Changes7}">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn DisplayMemberBinding="{Binding Path=Name}" Header="Name" />
<GridViewColumn DisplayMemberBinding="{Binding Path=Value}" Header="Value" Width="100" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
<ListView Grid.Row="1" Grid.Column="3" ItemsSource="{Binding Path=Changes8}">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn DisplayMemberBinding="{Binding Path=Name}" Header="Name" />
<GridViewColumn DisplayMemberBinding="{Binding Path=Value}" Header="Value" Width="100" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
</Grid>
</UserControl>
ViewModel
using BindingHang.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace BindingHang.ViewModels
{
public class MainVM : ViewModelBase
{
#region << Fields >>
private readonly int _maxCount = 1000;
private readonly int _delay = 20;
#endregion
#region << Constructor >>
public MainVM()
{
Initialize();
}
#endregion
#region << Properties >>
private readonly List<ChangeModel> _changes = new List<ChangeModel>();
public IEnumerable<ChangeModel> Changes1 => _changes.Skip((int)(_maxCount / 8) * 0).Take((int)(_maxCount / 8));
public IEnumerable<ChangeModel> Changes2 => _changes.Skip((int)(_maxCount / 8) * 1).Take((int)(_maxCount / 8));
public IEnumerable<ChangeModel> Changes3 => _changes.Skip((int)(_maxCount / 8) * 2).Take((int)(_maxCount / 8));
public IEnumerable<ChangeModel> Changes4 => _changes.Skip((int)(_maxCount / 8) * 3).Take((int)(_maxCount / 8));
public IEnumerable<ChangeModel> Changes5 => _changes.Skip((int)(_maxCount / 8) * 4).Take((int)(_maxCount / 8));
public IEnumerable<ChangeModel> Changes6 => _changes.Skip((int)(_maxCount / 8) * 5).Take((int)(_maxCount / 8));
public IEnumerable<ChangeModel> Changes7 => _changes.Skip((int)(_maxCount / 8) * 6).Take((int)(_maxCount / 8));
public IEnumerable<ChangeModel> Changes8 => _changes.Skip((int)(_maxCount / 8) * 7).Take((int)(_maxCount / 8));
#endregion
#region << Methods >>
private void Initialize()
{
for (int i = 1; i <= _maxCount; i++)
{
_changes.Add(new ChangeModel
{
Name = "Item " + i,
Value = i
});
}
Routine();
}
private void Routine()
{
Task.Run(async () =>
{
while (true)
{
foreach (var change in _changes)
{
_ = Application.Current?.Dispatcher.BeginInvoke(new Action(() => change.ChangeValue()));
}
await Task.Delay(_delay);
}
});
}
#endregion
}
}
Model
using BindingHang.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace BindingHang.Models
{
public class ChangeModel : ViewModelBase
{
#region << Fields >>
private readonly double _minValue = 0;
private readonly double _maxValue = 10000;
private bool _direction = false;
#endregion
#region << Constructor >>
public ChangeModel()
{
}
#endregion
#region << Properties >>
public string Name { get; set; }
private double _value = 0;
public double Value
{
get => _value;
set => SetValue(ref _value, value);
}
#endregion
#region << Methods >>
public void ChangeValue()
{
if (Value == _minValue)
_direction = true;
else if (Value == _maxValue)
_direction = false;
double temp = Value;
if (_direction)
temp++;
else
temp--;
Value = temp;
}
#endregion
}
}
Related
Below is xaml and ListView:
<ListView x:Name="lvImages" ItemsSource="{Binding Path=resimGuncelle}" SelectedItem="{Binding Path=ID}">
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Image Name="MyImage" Source="{Binding RESIM_YOLU}" Width="120" Height="110" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Title" DisplayMemberBinding="{Binding FileName}" x:Name="txtx" x:Uid="dd" />
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Style="{StaticResource DaireButtonResimSil}" x:Name="btndil" Click="btndil_Click"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
I want to get Selected item ID , something like this:
private void btndil_Click(object sender, RoutedEventArgs e)
{
var selectedImageId = ((ResimGuncelleme)lvImages.SelectedItem).ID;
}
If i am getting this right, you have an ItemDataModel for your ListView items, and it has an Id property. Each time you click on a row predefined button you want to get that row item's Id property (without selecting the row, otherwise you could simply check the ListView's SelectedItem property).
Assuming your ItemModel looks something like this:
public class ItemModel
{
public string Id { get; set; }
public BitmapSource ResimYolu { get; set; }
public string FileName { get; set; }
}
In your xaml you could pass the item where the button was clicked in the Button's Tag using a RelativeSource binding:
<Grid>
<ListView x:Name="lvImages" ItemsSource="{Binding Path=ResimGuncelle}" SelectedItem="{Binding Path=Id}">
<ListView.View>
<GridView>
<GridViewColumn Header="Image">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Image Name="MyImage" Source="{Binding ResimYolu}" Width="120" Height="110" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Title" DisplayMemberBinding="{Binding FileName}" x:Name="txtx" x:Uid="dd" />
<GridViewColumn Header="Button">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button x:Name="btndil" Tag="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListViewItem}}}" Content="Button" Click="btndil_Click" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
And you can get that item's id from your button's click handler:
private void btndil_Click(object sender, RoutedEventArgs e)
{
var item=((sender as Button)?.Tag as ListViewItem)?.DataContext;
var itemId = (item as ItemModel)?.Id;
}
Ps: this isn't a very clean way to do that!
I have a ListView that I need to populate with some text data.
Currently my ListViewItem look this way (2 columns):
Name Number of files Files finished
XAML:
<ListView.View>
<GridView>
</GridView>
</ListView.View>
Here i have all my GridViewColumnHeader and my Binding data for example Name property:
<!-- file name column -->
<GridViewColumn>
<GridViewColumnHeader Content="File name" />
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
<GridViewColumn>
What i want to do now is to see my Name in first line and NumberOfFiles and FilesFinished in second line:
So after quick search i found this solution.
So i add this:
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
<StackPanel Grid.Column="1">
<TextBlock Text="{Binding NumberOfFiles}" />
<TextBlock Text="{Binding FilesFinished}" />
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
So after add my files into my ListView i cannot see any file, so i try to remove my ListView.View and still the files missing.
What i dong wrong ?
It's look fine. I just add listview name.
<Grid>
<ListView Name="ListViewFiles">
<ListView.View>
<GridView AllowsColumnReorder="true" ColumnHeaderToolTip="Authors">
<GridViewColumn Header="File name" Width="120" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="NumberOfFiles" Width="120" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding NumberOfFiles}"/>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Code Sample. Maybe you forget ListViewFiles.ItemsSource = items;
public MainWindow()
{
InitializeComponent();
List<File> items = new List<File>();
items.Add(new File() { Name = "File One", NumberOfFiles = 2, Filesfished = "Yes" });
items.Add(new File() { Name = "File Two", NumberOfFiles = 2, Filesfished = "No" });
ListViewFiles.ItemsSource = items;
}
public class File
{
public string Name { get; set; }
public int NumberOfFiles { get; set; }
public string Filesfished { get; set; }
}
I want implement ProgressBar insine my ListView:
<ListView Name="lvTest" ItemsSource="{Binding PersonList}" Margin="308,45,268,473">
<ListView.View>
<GridView>
<GridViewColumn Width="390" Header="File name" DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn Width="50" Header="Progress">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ProgressBar Maximum="100" Value="{Binding Progress}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
My class example:
internal class MyData
{
public string Name { get; set; }
public int Progress { get; set; }
}
And the code behind:
var items = new ObservableCollection<MyData>();
items.Add(new MyData() { Name = "Some", Progress = 25 });
items.Add(new MyData() { Name = "Another", Progress = 91 });
lvTest.ItemsSource = items;
And this is the result: http://s12.postimg.org/3mgcwqbvh/image.png
As you can see my progress bar is empty and all i can see is dot inside.
Here with text in the progressbar.
<ListView Name="lvTest">
<ListView.Resources>
<DataTemplate x:Key="MyDataTemplate">
<Grid Margin="-6">
<ProgressBar Maximum="100" Value="{Binding Progress}" Width="{Binding Path=Width, ElementName=ProgressCell}" Height="10" Margin="0"/>
<TextBlock Text="{Binding Progress, StringFormat={}{0}%}" HorizontalAlignment="Center"/>
</Grid>
</DataTemplate>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Width="390" Header="File name" DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn x:Name="ProgressCell" Width="50" Header="Progress" CellTemplate="{StaticResource MyDataTemplate}" />
</GridView>
</ListView.View>
</ListView>
The Problem is the size of the Cell. Your ProgressBar is visible - but all you can see is the little dot.
Bind the ProgressBar Width to the Width of the Cell.
<ListView Name="lvTest">
<ListView.View>
<GridView>
<GridViewColumn Width="390" Header="File name" DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn x:Name="ProgressCell" Width="50" Header="Progress">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ProgressBar Maximum="100" Value="{Binding Progress}" Width="{Binding Path=Width, ElementName=ProgressCell}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Adding a width property to the progress bar should solve your issue, i.e.
<ProgressBar Maximum="100" Value="{Binding Path=Progress}" Width="100"/>
To switch between two ItemTemplates in my ListView based on the current Item type, I implemented a DataTemplateSelector. I added it via Binding to the ListView. But if I set a breakpoint, it never gets called. I tried everything, nothing works.
public class ListViewTemplateSelector : DataTemplateSelector
{
public DataTemplate SectionTemplate { get; set; }
public DataTemplate EntryTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item is Section)
{
return SectionTemplate;
}
if (item is Entry)
{
return EntryTemplate;
}
return base.SelectTemplate(item, container);
}
}
XAML:
<ListView DataContext="{Binding ElementName=This}" x:Name="list" Margin="200,25,0,0" ItemsSource="{Binding CurrentSelection}" ItemTemplateSelector="{StaticResource TemplateSelector}">
<ListView.View>
<GridView>
<GridViewColumn Header="ID" DisplayMemberBinding="{Binding ID}" Width="100" />
<GridViewColumn Header="Value" DisplayMemberBinding="{Binding Value}" Width="300" />
</GridView>
</ListView.View>
</ListView>
<DataTemplate x:Key="sectionTemplate">
<StackPanel Orientation="Horizontal">
<Image Width="16" Height="16" Source="\Icons\blue-folder.png" />
<TextBlock Text="{Binding ID}" Margin="5,0,0,0" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="entryTemplate">
<StackPanel Orientation="Horizontal">
<Image Width="16" Height="16" Source="\Icons\ui-text-field-medium.png" />
<TextBlock Text="{Binding ID}" Margin="5,0,0,0" />
</StackPanel>
</DataTemplate>
<sdk:ListViewTemplateSelector x:Key="TemplateSelector" SectionTemplate="{StaticResource sectionTemplate}" EntryTemplate="{StaticResource entryTemplate}" />
Has anybody an idea how to fix that?
Thanks R
From GridView Overview > GridView Layout and Style > Defining and Styling Columns in a GridView:
When defining the data field to display in a GridViewColumn, use the
DisplayMemberBinding, CellTemplate, or CellTemplateSelector
properties. The DisplayMemberBinding property takes precedence over
either of the template properties.
Hence you would have to remove the DisplayMemberBinding from your GridViewColumns and set the CellTemplateSelector instead of the ListView's ItemTemplateSelector:
<GridView>
<GridViewColumn Header="ID" Width="100"
CellTemplateSelector="{StaticResource TemplateSelector}"/>
<GridViewColumn Header="Value" Width="300"
DisplayMemberBinding="{Binding Value}"/>
</GridView>
I am facing issue when i am creating more than one dataview for datatable then binding is not working properly for new instances. Pleae help me to sort out this....
Have anyone have solution for this issue ? Please refer below for more details
Previous Post:
" we are experiencing the PropertyChange event on DataRowView not being raised for new Dataview instances.This appears to be an ADO bug, not WPF. After the app creates a new DataView, WPF subscribes to change events from the DataView's only member (a DataRowView), and unsubscribes to change events from the old DataRowView. Then somehow ADO changes the new DataView without any notification, replacing the new DataRowView with the old one. Now changes to the Name column affect the old DataRowView, and WPF never hears about them because it's listening to the new DataRowView."
Thanks in advance..
Code :
<Window x:Class="WpfStudy.GridView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfStudy"
Height="400" Width="500" Title="Binding Listview with Mulit ItemSource Options">
<Window.Resources>
<local:NameConverter x:Key="NameConverter"/>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel>
<Button Click="Button_Click">Click</Button>
<ListView Name="ListviewALL" >
<ListView.View>
<GridView>
<GridViewColumn Width="140" Header="Binding Label" >
<GridViewColumn.DisplayMemberBinding>
<MultiBinding Converter="{StaticResource NameConverter}">
<Binding Path="LastName" />
<Binding Path="FirstName" />
</MultiBinding>
</GridViewColumn.DisplayMemberBinding>
</GridViewColumn>
<GridViewColumn Width="140">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Name="FirstName" FontFamily="Lucida Console" Text="{Binding FirstName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="200" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="140">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Name="LastName" FontFamily="Lucida Console" Text="{Binding LastName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="200" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
<ListView Name="Listview" Grid.Row="1">
<ListView.View>
<GridView>
<GridViewColumn Width="140" Header="Binding Label" >
<GridViewColumn.DisplayMemberBinding>
<MultiBinding Converter="{StaticResource NameConverter}">
<Binding Path="LastName" />
<Binding Path="FirstName" />
</MultiBinding>
</GridViewColumn.DisplayMemberBinding>
</GridViewColumn>
<GridViewColumn Width="140">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Name="FirstName" FontFamily="Lucida Console" Text="{Binding FirstName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="200" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="140">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Name="LastName" FontFamily="Lucida Console" Text="{Binding LastName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="200" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<ListView Name="Listview1" Grid.Row="2">
<ListView.View>
<GridView>
<GridViewColumn Width="140" Header="Binding Label" >
<GridViewColumn.DisplayMemberBinding>
<MultiBinding Converter="{StaticResource NameConverter}">
<Binding Path="LastName" />
<Binding Path="FirstName" />
</MultiBinding>
</GridViewColumn.DisplayMemberBinding>
</GridViewColumn>
<GridViewColumn Width="140">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Name="FirstName" FontFamily="Lucida Console" Text="{Binding FirstName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="200" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="140">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Name="LastName" FontFamily="Lucida Console" Text="{Binding LastName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="200" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
Converter :
namespace WpfStudy
{
public class NameConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
StringBuilder sb=new StringBuilder();
foreach(string val in values)
{
if (sb.Length != 0)
sb.Append(" ");
sb.Append(val);
}
return sb.ToString();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
Binding Source
- i am binding datatable source with 3 list view with differnet dataview. if we create more view instance then two way binding is not working.xaml not getting updated from source.
private void loadDatatable()
{
DataTable dt = new DataTable();
dt.Columns.Add("FirstName");
dt.Columns.Add("LastName");
dt.Columns.Add("Userid");
DataRow dr = dt.NewRow();
dr[0] = "Siva";
dr[1] = "Jagan";
dr[2] = "JS";
dt.Rows.Add(dr);
DataRow dr1 = dt.NewRow();
dr1[0] = "Raam";
dr1[1] = "John";
dr1[2] = "RJ";
dt.Rows.Add(dr1);
ListviewALL.ItemsSource = dt.DefaultView;
dv1 = new DataView(dt);
dv1.RowFilter = "FirstName like'S%'";
dv2 = new DataView(dt);
dv2.RowFilter = "FirstName like 'R%'";
Listview.ItemsSource = dv1;
Listview1.ItemsSource = dv2;
}
what happens when you take a BindingListCollectionView or ICollectionView instead of the Dataview to filter your stuff?
EDIT:
i tried it out and the following works:
public BindingListCollectionView View1 { get; set; }
public BindingListCollectionView View2 { get; set; }
View1 = new BindingListCollectionView(new DataView(Dt) { RowFilter = "FirstName like 'R%'" });
View2 = new BindingListCollectionView(new DataView(Dt) { RowFilter = "FirstName like 'S%'"});
Add, Modify and Delete works.
EDIT2 my sample code: update to fullfill your requirements. editing through the textbox in any listview works!
public class Viewmodel
{
public DataTable Dt { get; set; }
public BindingListCollectionView View1 { get; set; }
public BindingListCollectionView View2 { get; set; }
public Viewmodel()
{
Dt = new DataTable();
Dt.Columns.Add("Name");
Dt.Columns.Add("VorName");
DataRow dr = Dt.NewRow();
dr[0] = "Siva";
dr[1] = "Jagan";
Dt.Rows.Add(dr);
DataRow dr1 = Dt.NewRow();
dr1[0] = "Raam";
dr1[1] = "John";
Dt.Rows.Add(dr1);
View1 = new BindingListCollectionView(new DataView(Dt) { RowFilter = "Name like 'R%'" });
View2 = new BindingListCollectionView(new DataView(Dt){RowFilter = "Name like 'S%'"});
}
}
window.xaml.cs
public partial class MainWindow : Window
{
private Viewmodel _data;
public MainWindow()
{
InitializeComponent();
this._data = new Viewmodel();
this.DataContext = _data;
}
}
window.xaml
<Window.Resources>
<local:NameConverter x:Key="NameConverter"/>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="138*" />
<ColumnDefinition Width="209*" />
<ColumnDefinition Width="156*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="76*" />
<RowDefinition Height="235*" />
</Grid.RowDefinitions>
<ListView ItemsSource="{Binding Dt}" Grid.Column="0" Grid.Row="1">
<ListView.View>
<GridView>
<GridViewColumn Width="140" Header="Binding Label" >
<GridViewColumn.DisplayMemberBinding>
<MultiBinding Converter="{StaticResource NameConverter}">
<Binding Path="Name" />
<Binding Path="VorName" />
</MultiBinding>
</GridViewColumn.DisplayMemberBinding>
</GridViewColumn>
<GridViewColumn Header="Name" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Name="FirstName" FontFamily="Lucida Console" Text="{Binding Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="200" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="VorName" DisplayMemberBinding="{Binding VorName}">
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<ListView ItemsSource="{Binding View1}" Grid.Column="1" Grid.Row="1">
<ListView.View>
<GridView>
<GridViewColumn Width="140" Header="Binding Label" >
<GridViewColumn.DisplayMemberBinding>
<MultiBinding Converter="{StaticResource NameConverter}">
<Binding Path="Name" />
<Binding Path="VorName" />
</MultiBinding>
</GridViewColumn.DisplayMemberBinding>
</GridViewColumn>
<GridViewColumn Header="Name" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Name="FirstName" FontFamily="Lucida Console" Text="{Binding Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="200" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="VorName" DisplayMemberBinding="{Binding VorName}">
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<ListView ItemsSource="{Binding View2}" Grid.Column="2" Grid.Row="1">
<ListView.View>
<GridView>
<GridViewColumn Width="140" Header="Binding Label" >
<GridViewColumn.DisplayMemberBinding>
<MultiBinding Converter="{StaticResource NameConverter}">
<Binding Path="Name" />
<Binding Path="VorName" />
</MultiBinding>
</GridViewColumn.DisplayMemberBinding>
</GridViewColumn>
<GridViewColumn Header="Name" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Name="FirstName" FontFamily="Lucida Console" Text="{Binding Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="200" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="VorName" DisplayMemberBinding="{Binding VorName}">
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
Try this after each addition ...
dt.AcceptChanges();
And if that doesnt work then reset the row filter
var tempFilter = dt.DefaultView.RowFilter;
dt.DefaultView.RowFilter = string.empty;
dt.DefaultView.RowFilter = tempFilter;