powered by simpleCommunicator - 2.0.50     © 2025 Programmizd 02
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / бага DataGrid
2 сообщений из 2, страница 1 из 1
бага DataGrid
    #39018952
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
<Window x:Class="WpfApplication27.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        xmlns:linq="clr-namespace:System.Linq;assembly=System.Core"
        Title="MainWindow" Height="350" Width="825" >
    <Window.Resources>
        <ObjectDataProvider x:Key="DataProvider" 
                            ObjectType="{x:Type linq:Enumerable}"
                            MethodName="Range">
            <ObjectDataProvider.MethodParameters>
                <system:Int32>10000000</system:Int32>
                <system:Int32>10000040</system:Int32>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
        <DataTemplate x:Key="CellTemplate" >
            <Border Height="50" Width="200" >
                <TextBlock Text="{Binding}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </Border>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <DataGrid ItemsSource="{Binding Source={StaticResource DataProvider}}"
                  EnableColumnVirtualization="True"
                  EnableRowVirtualization="True"
                  AutoGenerateColumns="False"
                  HeadersVisibility="All"
                  
                  Grid.Column="1">
            <DataGrid.RowHeaderStyle>
                <Style TargetType="{x:Type DataGridRowHeader}">
                    <Setter Property="Content" Value="{Binding}"/>
                    <Setter Property="Width" Value="300"/>
                </Style>
            </DataGrid.RowHeaderStyle>
            <DataGrid.Columns>
                <DataGridTemplateColumn CellTemplate="{StaticResource CellTemplate}"/>
                <DataGridTemplateColumn CellTemplate="{StaticResource CellTemplate}"/>
                <DataGridTemplateColumn CellTemplate="{StaticResource CellTemplate}"/>
                <DataGridTemplateColumn CellTemplate="{StaticResource CellTemplate}"/>
                <DataGridTemplateColumn CellTemplate="{StaticResource CellTemplate}"/>
                <DataGridTemplateColumn CellTemplate="{StaticResource CellTemplate}"/>
                <DataGridTemplateColumn CellTemplate="{StaticResource CellTemplate}"/>
                <DataGridTemplateColumn CellTemplate="{StaticResource CellTemplate}"/>
                <DataGridTemplateColumn CellTemplate="{StaticResource CellTemplate}"/>
                <DataGridTemplateColumn CellTemplate="{StaticResource CellTemplate}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>


Если уменьшить окно, будет плохо :( косяк связан с тем, что включена виртуализации колонок, как только все колонки перестают быть видимыми, заголовки строк уменьшаются, потом расширяются и так далее.
...
Рейтинг: 0 / 0
бага DataGrid
    #39125467
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тоже нашел интересный баг. В общем-то, то, что приведено ниже, делать не рекомендуется, но, тем не менее.
Разметка:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
<Grid>
  <Grid.RowDefinitions>
    <RowDefinition/>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="Auto"/>
  </Grid.RowDefinitions>
  <DataGrid
    x:Name="dataGrid"
    ItemsSource="{Binding Items}"
    SelectionMode="Single"
    SelectedItem="{Binding SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
    IsSynchronizedWithCurrentItem="True"
    IsReadOnly="True"
    AutoGenerateColumns="False">
    <DataGrid.Columns>
      <DataGridTextColumn
        Binding="{Binding Path=A}"
        Header="A"
        Width="*"/>
      <DataGridTextColumn
        Binding="{Binding Path=B}"
        Header="B"
        Width="*"/>
    </DataGrid.Columns>
  </DataGrid>
  <Button
    Grid.Row="1"
    Content="Delete selected"
    Padding="5"
    Margin="5"
    HorizontalAlignment="Center"
    VerticalAlignment="Center"
    Command="{Binding DeleteCommand}"/>
  <Button
    Grid.Row="2"
    Content="Check binding"
    Padding="5"
    Margin="5"
    HorizontalAlignment="Center"
    VerticalAlignment="Center"
    Click="CheckBinding"/>
  <Button
    Grid.Row="3"
    Content="Go to last"
    Padding="5"
    Margin="5"
    HorizontalAlignment="Center"
    VerticalAlignment="Center"
    Command="{Binding GoLastCommand}"/>
</Grid>


Код:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
public partial class MainWindow : INotifyPropertyChanged
{
  [DllImport("kernel32.dll",
    EntryPoint = "AllocConsole",
    SetLastError = true,
    CharSet = CharSet.Auto,
    CallingConvention = CallingConvention.StdCall)]
  static extern int AllocConsole();

  public MainWindow()
  {
    InitializeComponent();
    AllocConsole();
    Items = new ObservableCollection<Foo>(Enumerable.Range(1, 10).Select(i => new Foo {A = i, B = i}).ToList());
    DeleteCommand = new RelayCommand(DeleteSelectedItem, () => SelectedItem != null);
    GoLastCommand = new RelayCommand(() => SelectedItem = Items.Last());
    SelectedItem = Items.First();
    DataContext = this;
  }

  public ObservableCollection<Foo> Items { get; private set; }
  public RelayCommand DeleteCommand { get; private set; }
  public RelayCommand GoLastCommand { get; private set; }

  void DeleteSelectedItem()
  {
    SelectedItem.B++;
    Items.Remove(SelectedItem);
  }

  Foo _selectedItem;
  public Foo SelectedItem
  {
    get { return _selectedItem; }
    set
    {
      Console.WriteLine("SelectedItem: {0}", value);
      _selectedItem = value;
      RaisePropertyChanged("SelectedItem");
      DeleteCommand.RaiseCanExecuteChanged();
    }
  }

  public event PropertyChangedEventHandler PropertyChanged;
  void RaisePropertyChanged(string propertyName)
  {
    var pc = PropertyChanged;
    if(pc!=null)
      pc(this, new PropertyChangedEventArgs(propertyName));
  }

  void CheckBinding(object sender, System.Windows.RoutedEventArgs e)
  {
    var b = dataGrid.GetBindingExpression(Selector.SelectedItemProperty);
    if (b==null)
    {
      Console.WriteLine("null");
      return;
    }
    Console.WriteLine("{0} {1} {2} {3}",b.Status, b.HasError, b.ParentBinding.Path.Path, b.ParentBinding.Mode);
  }
}

public class Foo
{
  public int A { get; set; }
  public int B { get; set; }
  public override int GetHashCode()
  {
    return A*10+B;
  }
  public override bool Equals(object obj)
  {
    var f = obj as Foo;
    return f!=null && f.A==A && f.B==B;
  }
  public override string ToString()
  {
    return string.Format("Foo {{ A={0}, B={1} }}", A, B);
  }
}


После выполнения DeleteCommand пропадает биндинг SelectedItem в направлении от target к source (от датагрида к модели) - навигация по записям в гриде не приводит к изменению SelectedItem, но изменение SelectedItem в модели отображается в гриде - как будто биндинг стал one-way. Но проверка биндинга показывает, что с ним всё в порядке - он TwoWay, Active, и не имеет ошибок. Причина - изменение перед удалением свойства сущности, которое участвует в вычислениях переопределенных GetHashCode и Equals - т.е. если в методе DeleteSelectedItem закомментарить строку с SelectedItem.B++, то всё будет работать нормально.
...
Рейтинг: 0 / 0
2 сообщений из 2, страница 1 из 1
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / бага DataGrid
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]