我创建了一个小型用户控件,其中包含ICollectionView和ObservableCollection。
ObservableCollection<LogMessage> messages;
public ObservableCollection<LogMessage> Messages
{
get { return messages; }
}
ICollectionView log;
public ICollectionView Log
{
get { return log; }
}
变量在UserControl的构造函数中设置
public LogFilter()
{
messages = new ObservableCollection<LogMessage>();
log = new CollectionView(messages);
InitializeComponent();
#if DEBUG
messages.Add(new LogMessage("This is a general Message", MessageType.General));
messages.Add(new LogMessage("This is a server Message", MessageType.Server));
messages.Add(new LogMessage("This is an info", MessageType.Info));
messages.Add(new LogMessage("This is an error", MessageType.Error));
messages.Add(new LogMessage("This is a warning", MessageType.Warning));
#endif
}
UserControl中的ListView绑定到日志
<ListView x:Name="LogView" Grid.Row="0" ItemContainerStyle="{StaticResource LogMessageStyle}" ItemsSource="{Binding Log, ElementName=LogControl}" >
在ListView下面,有一个Checkbox绑定到一个布尔值,表示是否应该过滤某一行。
<CheckBox IsChecked="{Binding HideServer, ElementName=LogControl}" VerticalAlignment="Center" Width="75">
public bool filterServer(object o)
{
LogMessage m = o as LogMessage;
if ((m.MessageType == MessageType.Server) && (hideServer == true))
return false;
return true;
}
public bool HideServer
{
get
{
return hideServer;
}
set
{
hideServer = value;
if (hideServer)
Log.Filter = new Predicate<object>(filterServer);
else
Log.Filter = null;
notifyPropertyChanged();
log.Refresh();
}
}
检查复选框后,过滤器会正确添加到ICollectionView,但不会过滤列表框的内容。不调用filterServer(object o)函数。这段代码有问题吗?我使用调试器逐步完成了代码,似乎Log.Refresh()没有效果。
PropertyChanged事件定义为
public event PropertyChangedEventHandler PropertyChanged;
private void notifyPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
LogMessage和MessageType定义为
public class LogMessage
{
public DateTime Timestamp { get; private set; }
public LogFilter.MessageType MessageType { get; private set; }
public string Message { get; private set; }
public LogMessage(string Message)
{
initalize(DateTime.Now, LogFilter.MessageType.General, Message);
}
public LogMessage(string Message, DateTime Timestamp)
{
initalize(Timestamp, LogFilter.MessageType.General, Message);
}
public LogMessage(string Message, LogFilter.MessageType MessageType)
{
initalize(DateTime.Now, MessageType, Message);
}
public LogMessage(string Message, DateTime Timestamp, LogFilter.MessageType MessageType)
{
initalize(Timestamp, MessageType, Message);
}
private void initalize(DateTime timestamp, LogFilter.MessageType messageType, string message)
{
Timestamp = timestamp;
MessageType = messageType;
Message = message;
}
}
public enum MessageType
{
Server,
Info,
Warning,
Error,
General
}
答案 0 :(得分:1)
我不知道这是否是造成问题的原因,但是CollectionView
类的文档说:
您不应在代码中创建此类的对象
相反,可能的解决方案是使用ICollectionView
获取CollectionViewSource.GetDefaultView
:
log = CollectionViewSource.GetDefaultView(messages);
请注意,您不需要公开Log
并绑定它;您可以绑定到Messages
,因为在场景后面,WPF将使用集合的默认视图,这与CollectionViewSource.GetDefaultView
返回的视图相同。