Гость
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / бага DataGrid / 2 сообщений из 2, страница 1 из 1
29.07.2015, 17:46
    #39018952
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
бага DataGrid
Код: 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
11.12.2015, 06:52
    #39125467
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
бага DataGrid
Тоже нашел интересный баг. В общем-то, то, что приведено ниже, делать не рекомендуется, но, тем не менее.
Разметка:
Код: 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
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / бага DataGrid / 2 сообщений из 2, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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