我正在尝试对我的网格进行一点样式化。我想根据每行中的信息为行着色。我在这次手术中犯了一个严重的错误。此外,这是在应用程序启动期间发生的。这是我在WPF中的第一步,我试图制作一些有用的记录器,但现在我遇到了巨大的障碍。
错误:当ItemsSource正在使用时,操作无效。使用ItemsControl访问和修改元素。而是ItemsSource
值得一提的是,我使用静态列表作为网格的ItemSource。下面是我的一些代码。
<DataGrid DockPanel.Dock="Bottom" Height="Auto" ItemsSource="{Binding Source={x:Static Log:Logger.LogCollection}, Mode=OneWay}" FontSize="12" FontFamily="Segoe UI">
<i:Interaction.Behaviors>
<fw:ScrollGridView/>
</i:Interaction.Behaviors>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding LogType}" Value="Info">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid>
</DockPanel>
和类
public static class Logger
{
private static ObservableCollection<LogMessage> _logCollection = new ObservableCollection<LogMessage>();
public static ObservableCollection<LogMessage> LogCollection
{
get { return Logger._logCollection; }
set
{
if (_logCollection.Count > 500)
{
_logCollection.RemoveAt(_logCollection.Count - 1);
}
Logger._logCollection = value;
}
}
public static void Log(string message)
{
Log(LogType.Info, message, null);
}
public static void Log(LogType type, string message, string exception)
{
LogCollection.Add(new LogMessage { Type = type, Time = DateTime.Now, Message = message, Exception = exception });
}
}
日志消息:
public enum LogType
{
Debug,
Warning,
Error,
Info
}
public class LogMessage
{
public LogType Type { get; set; }
public DateTime Time { get; set; }
public string Message { get; set; }
public string Exception { get; set; }
}
谢谢!
确保在DataGrid.Columns
中为DataGrid
定义列,如下所示,而不是直接在DataGrid
中定义列,并在DataGrid.Resource
中定义Style
<DataGrid>
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding LogType}" Value="Info">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn/>
</DataGrid.Columns>
</DataGrid>
它很有帮助!!!现在看起来是这样的:
<DataGrid DockPanel.Dock="Bottom" Height="Auto" ItemsSource="{Binding Source={x:Static Log:Logger.LogCollection}, Mode=OneWay}" FontSize="12" FontFamily="Segoe UI" AutoGenerateColumns="False">
<i:Interaction.Behaviors>
<fw:ScrollGridView/>
</i:Interaction.Behaviors>
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding Type}" Value="Info">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn MinWidth="30" Header="Type">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Width="16"
Height="16"
Source="{Binding Path=Type,
UpdateSourceTrigger=PropertyChanged,
Converter={StaticResource ImageTypeConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Time"
Binding="{Binding Time}"/>
<DataGridTextColumn Header="Message"
Binding="{Binding Message}"
Width="1200">
<DataGridTextColumn.ElementStyle>
<Style>
<Setter Property="TextBlock.TextWrapping" Value="Wrap" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Exception"
Binding="{Binding Exception}"
Width="1200">
<DataGridTextColumn.ElementStyle>
<Style>
<Setter Property="TextBlock.TextWrapping" Value="Wrap" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</DockPanel>
我还有一个问题。在我添加DataGrid之前。完美地为我的行为工作者提供资源,之后事件停止了。这很奇怪,因为我并没有改变向网格源添加项目的方式。
public class ScrollGridView : Behavior<DataGrid>
{
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.SelectionChanged += new SelectionChangedEventHandler(AssociatedObject_SelectionChanged);
}
private void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (sender is DataGrid)
{
DataGrid grid = (sender as DataGrid);
if (grid.Items.Count > 0)
{
var border = VisualTreeHelper.GetChild(grid, 0) as Decorator;
if (border != null)
{
var scroll = border.Child as ScrollViewer;
if (scroll != null && !scroll.IsMouseOver) scroll.ScrollToEnd();
}
}
}
}
protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.SelectionChanged -= new SelectionChangedEventHandler(AssociatedObject_SelectionChanged);
}
}