我的DataModel:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
namespace LogViewerApplication
{
public class LogRead
{
string _path;
List<string> _strList;
public List<string> StrList
{
get { return _strList; }
}
public LogRead()
{
_path = @"D:\Log viewer (project)\Test_log.txt";
}
/// <summary>
/// To read the file and then to store the records in a List.
/// </summary>
public void GetFile()
{
//_path = @"D:\Log viewer (project)\presentation_log.txt";
string _pattern = @"^\d{2}/\d{2}/\d{4}";
_strList = new List<string>();
using (StreamReader objReader = new StreamReader(_path))
{
string sLine = "";
while ((sLine = objReader.ReadLine()) != null)
{
_strList.Add(sLine);
}
}
int j;
string sub;
for (int k = 0; k < _strList.Count; k++)
{
if (!Regex.IsMatch(_strList[k], _pattern))
{
j = k;
sub = _strList[k];
_strList[j - 1] = _strList[j - 1] + " " + sub;
_strList.RemoveAt(k);
//Console.WriteLine(strlist[k]);
//Console.WriteLine();
k--;
}
}
}
}
public enum Severe { Normal, Debug, Critical }
public class LogViewerModel
{
public DateTime Datetime { get; set; }
public string Source { get; set; }
public Severe Severity { get; set; }
public string Message { get; set; }
}
}
我的ViewModel:
namespace LogViewerApplication
{
class LogViewerViewModel:INotifyPropertyChanged
{
ObservableCollection<LogViewerModel> _logViewerModelCollection;
LogRead _logRead;
ICollectionView _viewSource;
//GroupFilter gf;
public ICollectionView ViewSource
{
get
{
if(_viewSource==null)
{
_viewSource = CollectionViewSource.GetDefaultView(_logViewerModelCollection);
}
return _viewSource;
}
}
#region Commands
#region SetColorCommand
private RelayCommand _setColorCommand;
public ICommand SetColorCommand
{
get
{
if (_setColorCommand == null)
{
_setColorCommand = new RelayCommand(SetColor);
}
return _setColorCommand;
}
}
private void SetColor(Object param)
{
if (_norm && !_dbg && !_crtcl)
{
_viewSource.Filter = delegate(object item)
{
return ((LogViewerModel)item).Severity == Severe.Normal;
};
}
else if (_dbg && !_norm && !_crtcl)
{
_viewSource.Filter = delegate(object item)
{
return ((LogViewerModel)item).Severity == Severe.Debug;
};
}
else if (_crtcl && !_norm && !_dbg)
{
_viewSource.Filter = delegate(object item)
{
return ((LogViewerModel)item).Severity == Severe.Critical;
};
}
else if (_norm && _dbg && !_crtcl)
{
_viewSource.Filter = delegate(object item)
{
return ((LogViewerModel)item).Severity == Severe.Normal || ((LogViewerModel)item).Severity == Severe.Debug;
};
}
else if (_norm && _crtcl && !_dbg)
{
_viewSource.Filter = delegate(object item)
{
return ((LogViewerModel)item).Severity == Severe.Normal || ((LogViewerModel)item).Severity == Severe.Critical;
};
}
else if (_dbg && _crtcl && !_norm)
{
_viewSource.Filter = delegate(object item)
{
return ((LogViewerModel)item).Severity == Severe.Debug || ((LogViewerModel)item).Severity == Severe.Critical;
};
}
else if (_norm && _dbg && _crtcl)
{
_viewSource.Filter = delegate(object item)
{
return true;
};
}
else
{
_viewSource.Filter = delegate(object item)
{
return false;
};
}
}
#endregion
#region SearchCommand
private RelayCommand _searchCommand;
public ICommand SearchCommand
{
get
{
if (_searchCommand == null)
{
_searchCommand = new RelayCommand(Search);
}
return _searchCommand;
}
}
private void Search(object param)
{
string str = param as string;
if (_searchSource == "Source")
{
_viewSource.Filter = delegate(object item)
{
if (string.IsNullOrEmpty(str))
{
return true;
}
else
{
int index = ((LogViewerModel)item).Source.IndexOf(str, 0, StringComparison.InvariantCultureIgnoreCase);
return index > -1;
}
//return ((LogViewerModel)item).Severity == Severe.Normal;
};
}
else if (_searchSource == "Message")
{
_viewSource.Filter = delegate(object item)
{
if (string.IsNullOrEmpty(str))
{
return true;
}
else
{
int index = ((LogViewerModel)item).Message.IndexOf(str, 0, StringComparison.InvariantCultureIgnoreCase);
return index > -1;
}
//return ((LogViewerModel)item).Severity == Severe.Normal;
};
}
else
{
_viewSource.Filter = delegate(object item)
{
return true;
};
}
}
#endregion
#region DateFilterCommand
private RelayCommand _dateFilterCommand;
public ICommand DateFilterCommand
{
get
{
if (_dateFilterCommand == null)
{
_dateFilterCommand = new RelayCommand(DateFilter);
}
return _dateFilterCommand;
}
}
private void DateFilter(object param)
{
string _startDate;
string _endDate;
if (string.IsNullOrEmpty(_startHour) && string.IsNullOrEmpty(_startMinute) && string.IsNullOrEmpty(_endHour) && string.IsNullOrEmpty(_endMinute))
{
_startDate = _startDay + "-" + StartMonth + "-" + _startYear;
_endDate = _endDay + "-" + _endMonth + "-" + _endYear + " " + "23" + ":" + "59" + ":" + "59";
try
{
DateTime startDate = Convert.ToDateTime(_startDate);
DateTime endDate = Convert.ToDateTime(_endDate);
_viewSource.Filter = delegate(object item)
{
return (((LogViewerModel)item).Datetime >= startDate) && (((LogViewerModel)item).Datetime <= endDate);
};
}
catch
{
MessageBox.Show("Please Enter a valid DATE range..!!!!");
}
}
else
{
_startDate = _startDay + "-" + StartMonth + "-" + _startYear + " " + _startHour + ":" + _startMinute;
_endDate = _endDay + "-" + _endMonth + "-" + _endYear + " " + _endHour + ":" + _endMinute + ":" + "59";
try
{
DateTime startDate = Convert.ToDateTime(_startDate);
DateTime endDate = Convert.ToDateTime(_endDate);
_viewSource.Filter = delegate(object item)
{
return (((LogViewerModel)item).Datetime >= startDate) && (((LogViewerModel)item).Datetime <= endDate);
};
}
catch
{
MessageBox.Show("Please Enter a valid DATE range..!!!!");
}
}
}
#endregion
#endregion
public LogViewerViewModel()
{
_logRead = new LogRead();
_logRead.GetFile();
_logViewerModelCollection= new ObservableCollection<LogViewerModel>();
loaddata();
//gf = new GroupFilter();
}
/// <summary>
/// It is used to split the string property wise and to store the data
/// into an ObservableCollection.
/// </summary>
public void loaddata()
{
int listSize = _logRead.StrList.Count;
DateTime dateTime;
string source;
Severe severity;
string message;
for (int k = 0; k < listSize; k++)
{
int flag = 0;
string str = _logRead.StrList[k];
//To check if a particular log entry is valid or not
//on the basis of "Severity".
foreach (string s in Enum.GetNames(typeof(Severe)))
{
bool check = Regex.IsMatch(str, string.Format(@"\b{0}\b", Regex.Escape(s)));
if (check)
{
flag = 1;
break;
}
}
//If log entry is Valid then execute the following Code.
if (flag == 1)
{
//dateTime = Convert.ToDateTime(str.Substring(0, 18));
dateTime = DateTime.ParseExact(str.Substring(0, 19), "dd/MM/yyyy HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
string lft = str.Substring(21, str.Length - 21);
int c = 4;
string delimStr = ":";
char[] delimiter = delimStr.ToCharArray();
string[] x = lft.Split(delimiter, c);
int size = x.Length;
if (size == 2)
{
source = x[0];
severity =(Severe)Enum.Parse(typeof(Severe),x[1].Trim());
message = " ";
AssignData(dateTime, source, severity, message);
}
else
{
for (int i = 0; i < size; i++)
{
if (x[i].Length == 1)
{
while (i < size - 1)
{
x[i] = x[i + 1];
i++;
}
Array.Resize(ref x, i);
break;
}
}
int len = x.Length;
if (len == 2)
{
source = x[0];
severity = (Severe)Enum.Parse(typeof(Severe),x[1].Trim());
message = " ";
AssignData(dateTime, source, severity, message);
}
else
{
if (len >= 4)
{
x[2] = x[2] + x[3];
Array.Resize(ref x, 3);
}
source = x[0];
severity = (Severe)Enum.Parse(typeof(Severe),x[1].Trim());
message = x[2].Trim();
AssignData(dateTime,source,severity,message);
}
}
}
}
}
/// <summary>
/// It is used to add the data into an ObservableCollection named as 'LogViewerModelCollection'.
/// </summary>
/// <param name="dateTime">DateTime for log entry</param>
/// <param name="source">Source File for log entry </param>
/// <param name="severity">Severity for log entry</param>
/// <param name="message">Description for log entry</param>
public void AssignData(DateTime dateTime,string source,Severe severity,string message)
{
_logViewerModelCollection.Add(new LogViewerModel
{
Datetime = dateTime,
Source = source,
Severity = severity,
Message = message
});
}
#region Properties
bool _norm=true;
bool _dbg = true;
bool _crtcl=true;
string _searchSource;
string _startDay;
string _startMonth;
string _startYear;
string _startHour;
string _startMinute;
string _endDay;
string _endMonth;
string _endYear;
string _endHour;
string _endMinute;
public bool LowChk
{
get { return _norm; }
set
{
_norm = value;
OnPropertyChanged("LowChk");
}
}
public bool MediumChk
{
get { return _dbg; }
set
{
_dbg = value;
OnPropertyChanged("MediumChk");
}
}
public bool HighChk
{
get { return _crtcl; }
set
{
_crtcl = value;
OnPropertyChanged("HighChk");
}
}
public string SearchSource
{
get { return _searchSource; }
set
{
_searchSource = value;
OnPropertyChanged("SearchSource");
}
}
public string StartDay
{
get { return _startDay; }
set { _startDay=value;}
}
public string StartMonth
{
get { return _startMonth; }
set { _startMonth = value; }
}
public string StartYear
{
get { return _startYear; }
set { _startYear=value;}
}
public string StartHour
{
get { return _startHour; }
set { _startHour=value;}
}
public string StartMinute
{
get { return _startMinute; }
set { _startMinute = value; }
}
public string EndDay
{
get { return _endDay; }
set { _endDay = value; }
}
public string EndMonth
{
get { return _endMonth; }
set { _endMonth = value; }
}
public string EndYear
{
get { return _endYear; }
set { _endYear=value;}
}
public string EndHour
{
get { return _endHour; }
set { _endHour=value;}
}
public string EndMinute
{
get { return _endMinute; }
set { _endMinute = value; }
}
#endregion
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
#endregion
}
}
RelayCommand的逻辑:
namespace LogViewerApplication
{
public class RelayCommand:ICommand
{
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
/// <summary>
/// Creates a new command that can always execute.
/// </summary>
/// <param name="execute">The execution logic.</param>
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
/// <summary>
/// Creates a new command.
/// </summary>
/// <param name="execute">The execution logic.</param>
/// <param name="canExecute">The execution status logic.</param>
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
//public event EventHandler CanExecuteChanged;
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
#endregion
}
}
APP.xaml代码: -
namespace LogViewerApplication
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
//base.OnStartup(e);
FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(System.Globalization.CultureInfo.CurrentCulture.IetfLanguageTag)));
LogViewerViewModel logViewerViewModel = new LogViewerViewModel();
LogViewer window = new LogViewer();
window.Show();
window.DataContext = logViewerViewModel;
}
}
}
XAML代码:
<Window.Resources>
<!--<ph:LogViewerViewModel x:Key="log"/>-->
<!--<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border
Name="Border"
Background="LightBlue"
BorderBrush="Black"
BorderThickness="1,1,1,1"
CornerRadius="6,6,0,0" >
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="12,2,12,2"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border" Property="Background" Value="LightBlue" />
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="Border" Property="Background" Value="LightGray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>-->
<!--<Style TargetType="{x:Type TabControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TabPanel
Grid.Row="0"
Panel.ZIndex="1"
Margin="0,0,4,-1"
IsItemsHost="True"
Background="Transparent" />
<Border
Grid.Row="1"
BorderBrush="Black"
BorderThickness="1"
CornerRadius="0, 12, 12, 12" >
<Border.Background>
<LinearGradientBrush>
<GradientStop Color="LightBlue" Offset="0" />
<GradientStop Color="White" Offset="1" />
</LinearGradientBrush>
</Border.Background>
<ContentPresenter ContentSource="SelectedContent" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>-->
<Style x:Key="ItemContStyle" TargetType="{x:Type ListViewItem}">
<Style.Resources>
<SolidColorBrush x:Key="TruBrush" Color="Green"/>
<SolidColorBrush x:Key="VinuBrush" Color="Red"/>
</Style.Resources>
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Style.Triggers>
<DataTrigger Binding="{Binding Severity}" Value="Debug">
<Setter Property="Background" Value="{StaticResource TruBrush}" />
</DataTrigger>
<DataTrigger Binding="{Binding Severity}" Value="Critical">
<Setter Property="Background" Value="{StaticResource VinuBrush}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.4*" />
<RowDefinition Height="0.6*" />
</Grid.RowDefinitions>
<ScrollViewer Grid.Row="0" Grid.Column="0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<ListView x:Name="_listView" x:FieldModifier="private" Grid.Row="0" Width="Auto" Height="Auto" Margin="8,9,11,0" ItemContainerStyle="{StaticResource ItemContStyle}" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding ViewSource}" >
<ListView.View>
<GridView x:Name="_gridView">
<GridViewColumn Width="150" DisplayMemberBinding="{Binding Datetime}" Header="Date/Time"/>
<GridViewColumn Width="220" DisplayMemberBinding="{Binding Source}" Header="Source"/>
<GridViewColumn Width="120" DisplayMemberBinding="{Binding Severity}" Header="Severity"/>
<GridViewColumn Width="Auto" DisplayMemberBinding="{Binding Message}">
<GridViewColumn.Header>
<GridViewColumnHeader Content="Message" HorizontalContentAlignment="Left"/>
</GridViewColumn.Header>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</ScrollViewer>
<TabControl Grid.Row="1" VerticalAlignment="Stretch" Width="Auto" Margin="8,9,11,0">
<TabItem Header="FilterBySeverity">
<StackPanel>
<Expander Header="Color Code" Margin="0,10,0,20" Width="100" HorizontalAlignment="Left" Expanded="Expander_Expanded">
<Expander.ToolTip>
<ToolTip>View Severity in Colors</ToolTip>
</Expander.ToolTip>
<StackPanel>
<RadioButton Margin="20,8,0,8">Enable</RadioButton>
<RadioButton Margin="20,0,0,8">Disable</RadioButton>
</StackPanel>
</Expander>
<CheckBox x:Name="_low" x:FieldModifier="private" Margin="8,10,0,12" IsChecked="{Binding LowChk, UpdateSourceTrigger=PropertyChanged}">Low</CheckBox>
<CheckBox x:Name="_medium" x:FieldModifier="private" Margin="8,0,0,12" IsChecked="{Binding MediumChk, UpdateSourceTrigger=PropertyChanged}">Medium</CheckBox>
<CheckBox x:Name="_high" x:FieldModifier="private" Margin="8,0,0,40" IsChecked="{Binding HighChk, UpdateSourceTrigger=PropertyChanged}">High</CheckBox>
<Button x:Name="_show" Width="100" Margin="8,0,0,0" HorizontalAlignment="Left" Command="{Binding Path=SetColorCommand}" >Show
<Button.BitmapEffect>
<BitmapEffectGroup>
<OuterGlowBitmapEffect/>
<DropShadowBitmapEffect/>
<BevelBitmapEffect/>
</BitmapEffectGroup>
</Button.BitmapEffect>
</Button>
</StackPanel>
</TabItem>
<TabItem Header="FilterByTimeDate">
<Grid Height="250" Width="600" Margin="0,20,350,100">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Row="0" FontSize="20" FontWeight="Bold" Height="80" Width="Auto">Enter the time range for your search</Label>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Width="50" Margin="0,30,5,0" FontSize="15" FontWeight="Bold">From:</Label>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" Height="40" Width="Auto">
<Label>Day:</Label>
<TextBox Margin="0,0,5,5" Height="20" Width="30" Text="{Binding Path=StartDay, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Label>Month:</Label>
<TextBox Margin="0,0,5,5" Height="20" Width="30" Text="{Binding Path=StartMonth, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Label>Year:</Label>
<TextBox Margin="0,0,0,5" Height="20" Width="80" Text="{Binding Path=StartYear, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" Height="30" Width="Auto">
<Label>Hour:</Label>
<TextBox Margin="0,0,5,5" Height="20" Width="30" Text="{Binding Path=StartHour, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Label>Minute:</Label>
<TextBox Margin="0,2,5,10" Height="20" Width="30" Text="{Binding Path=StartMinute, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
<Button Grid.Row="2" Height="30" Width="100" Command="{Binding DateFilterCommand}">Show</Button>
</Grid>
<Label Grid.Column="2" Width="30" Margin="15,30,2,0" FontSize="15" FontWeight="Bold">To:</Label>
<Grid Grid.Column="3">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" Height="40">
<Label>Day:</Label>
<TextBox Margin="0,7,10,15" Height="20" Width="30" Text="{Binding Path=EndDay, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Label>Month:</Label>
<TextBox Margin="0,7,10,15" Height="20" Width="30" Text="{Binding Path=EndMonth, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Label>Year:</Label>
<TextBox Margin="0,7,10,15" Height="20" Width="80" Text="{Binding Path=EndYear, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal" Height="30">
<Label>Hour:</Label>
<TextBox Margin="0,2,10,10" Height="20" Width="30" Text="{Binding Path=EndHour, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Label>Minute:</Label>
<TextBox Margin="0,2,10,10" Height="20" Width="30" Text="{Binding Path=EndMinute, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</Grid>
</Grid>
</Grid>
</TabItem>
<TabItem Header="Searching">
<Grid Height="150" Width="300">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" Margin="0,12,0,0" Width="82.033" Background="AliceBlue">FindWhat:</Label>
<Label Grid.Row="1" HorizontalAlignment="Right" Margin="0,14,0,0" Width="80.097">EnterText:</Label>
<ComboBox x:Name="FindWhat" x:FieldModifier="private" Grid.Row="0" Grid.Column="1" Margin="0,0,0,13" Text="{Binding Path=SearchSource, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<ComboBoxItem Content="Source"/>
<ComboBoxItem Content="Message"/>
</ComboBox>
<TextBox x:Name="EnterText" x:FieldModifier="private" Grid.Column="1" Grid.Row="1" Margin="0,14,0,0"/>
<Button Grid.Column="1" Grid.Row="2" Width="75" HorizontalAlignment="Left" Name="CoolTabButton" Margin="0,15,0,12" Command="{Binding SearchCommand}" CommandParameter="{Binding ElementName=EnterText, Path=Text}">OK</Button>
<!--Text="{Binding SearchingText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"-->
</Grid>
</TabItem>
</TabControl>
</Grid>
所以我们面临一个问题,当我选择另一个过滤器之后的过滤器然后我没有得到我的listview中的先前过滤数据..我的意思是第二个过滤器适用于一个新的列表....所有三个过滤器单独工作很好,但在链接工作时,所有过滤器总是在新的列表上工作,在之前的过滤列表... 伙计们请帮帮我.... 请给我一个正确的逻辑代码来解决这个问题....
由于
答案 0 :(得分:0)
您可以查看这是否符合您的需求:http://dotnetexplorer.blog.com/2011/04/07/wpf-itemscontrol-generic-staticreal-time-filter-custom-control-presentation/
这是一个多重过滤器组件,可以处理最常见的.net集合并将其自身附加到任何WPF ItemsControl
唯一的缺点是这是一个站在ItemsControl外面的组件......