简体   繁体   English

样式化DataGrid行WPF异常

[英]Styling DataGrid rows WPF exception

I'm trying to style my grid a little bit. 我正在尝试为网格设置一些样式。 I want to color rows based on information in the each row. 我想根据每一行中的信息为行着色。 I've got this nasty error during this operation. 在执行此操作期间,我遇到了这个令人讨厌的错误。 Moreover this is happening during application startup. 此外,这是在应用程序启动期间发生的。 This my first steps in WPF I'm trying to make some useful logger, but now I hit the huge wall. 这是我在WPF中迈出的第一步,我正在尝试制作一些有用的记录器,但是现在我碰壁了。

Error: Operation is not valid while ItemsSource is in use. 错误: 使用ItemsSource时操作无效。 Access and modify elements with ItemsControl.ItemsSource instead. 而是使用ItemsControl.ItemsSource访问和修改元素。

It is worth mentioning that I'm using static list as ItemSource to grid. 值得一提的是,我使用静态列表作为ItemSource来网格化。 Below some code of mine. 下面是我的一些代码。

<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>

And the class 和班级

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 });
    }
}

LogMessage: LogMessage:

    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; }
}

Thanks! 谢谢!

Make sure you define your Columns for DataGrid in DataGrid.Columns like below and not directly within DataGrid and define your Style in DataGrid.Resource 请确保您定义的列的DataGridDataGrid.Columns中像下面并没有直接DataGrid和定义StyleDataGrid.Resource

     <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>

It helped!!! 它帮助了!!! Now it looks like this: 现在看起来像这样:

<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>

And I have another one question. 我还有一个问题。 Before I have added DataGrid.Resources my behavior worker perfectly and after that the event stopped firing. 在我添加DataGrid.Resources我的行为工作者之前,此事件停止触发。 It is strange because I didn't change way of adding item to my grid source. 这很奇怪,因为我没有更改将项目添加到网格源的方式。

    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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM