Gu.Wpf.DataGrid2D icon indicating copy to clipboard operation
Gu.Wpf.DataGrid2D copied to clipboard

Scientific Notation for Numeric Data

Open kaneorotar opened this issue 6 years ago • 11 comments

Thank you for this amazing user control. I'm currently trying to use it to display large numbers best represented in scientific notation in my project.

I have tried modifying your code by manually assigning StringFormat of Binding and ItemStringFormatProperty of ItemControl. But the format of the result stays the same.

Can anyone please point me to the right direction on how this can be implemented?

Thanks.

kaneorotar avatar Mar 23 '18 23:03 kaneorotar

<DataGrid dataGrid2D:ItemsSource.Array2D="{Binding Data2D}"
          AutoGenerateColumns="False">
  <DataGrid.Columns>
    <DataGridTextColumn Binding="{Binding C0, StringFormat=F2}" Header="Col 1" />
    <DataGridTextColumn Binding="{Binding C1, StringFormat=F2}" Header="Col 2" />
  </DataGrid.Columns>
</DataGrid>

^ Seems to work, will not be much fun if the size is not fixed.

An alternative is to use the CellTemplate property like this:

<DataGrid dataGrid2D:ItemsSource.Array2D="{Binding Array2D}"
          IsReadOnly="True">
  <dataGrid2D:Cell.Template>
    <DataTemplate>
      <TextBlock Text="{Binding StringFormat=F2}" />
    </DataTemplate>
  </dataGrid2D:Cell.Template>
</DataGrid>

I'm not sure if DataGrid uses ItemStringFormat for anything. Maybe we can use it, what do you think @FoggyFinder?

JohanLarsson avatar Mar 24 '18 06:03 JohanLarsson

I suppose you can set dataTemplate for cell:

<DataTemplate x:Key="CellTemplate">
    <TextBlock Text="{Binding Path=., StringFormat=E5}" />
</DataTemplate>
dataGrid2D:Cell.Template="{StaticResource CellTemplate}"

if column count is fluent

FoggyFinder avatar Mar 24 '18 07:03 FoggyFinder

@JohanLarsson @FoggyFinder Thank you very much for the replies.

I have tried both of your solutions and then realized that I forgot to mention that I also want to edit the cells and have TwoWay binding. My 2D data can also vary in size, which makes it unfavorable to pre-define the columns.

This enables me to edit the cells but doesn't update the source:

<DataTemplate x:Key="dg2DCellTemplate">
    <TextBox Text="{Binding Path=., StringFormat=0.000000E+00, Mode=TwoWay, BindsDirectlyToSource=True, UpdateSourceTrigger=LostFocus, NotifyOnSourceUpdated=True}" BorderBrush="{x:Null}" />
</DataTemplate>
...
<DataGrid dataGrid2D:ItemsSource.Array2D="{Binding Path=Outputs[0].Matrix, Mode=TwoWay}" ColumnWidth="*" dataGrid2D:Cell.Template="{StaticResource dg2DCellTemplate}" />

On the other hand, TwoWay binding works when I'm not using CellTemplate.

Can you please shed some light on this?

Thanks.

kaneorotar avatar Mar 24 '18 22:03 kaneorotar

Normally when using dataTemplates for a DataGrid, you will use two templates: one for displaying, one for editing. Maybe that would help? The 2D datagrid allows for this also. If I remember correctly:

dataGrid2D:Cell.Template="{StaticResource CellTemplate}"

dataGrid2D:Cell.EditingTemplate="{StaticResource CellEditingTemplate}"

On Sat, Mar 24, 2018 at 11:50 PM, Kan Wang [email protected] wrote:

@JohanLarsson https://github.com/JohanLarsson @FoggyFinder https://github.com/FoggyFinder Thank you very much for the replies.

I have tried both of your solutions and then realized that I forgot to mention that I also want to edit the cells and have TwoWay binding.

This enables me to edit the cells but doesn't update the source:

    <DataTemplate x:Key="dg2DCellTemplate">
        <TextBox Text="{Binding Path=., StringFormat=0.000000E+00, Mode=TwoWay, BindsDirectlyToSource=True, UpdateSourceTrigger=LostFocus, NotifyOnSourceUpdated=True}" BorderBrush="{x:Null}" />
    </DataTemplate>

Can you please shed some light on this?

Thanks.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/GuOrg/Gu.Wpf.DataGrid2D/issues/29#issuecomment-375930635, or mute the thread https://github.com/notifications/unsubscribe-auth/ABpzEjYEEH4sBAESKKGQcq__q3EDX28nks5ths2zgaJpZM4S5epp .

-- To ensure safety and privacy, this email will selfdestruct in 5 seconds. Don't panic!

mennowo avatar Mar 25 '18 11:03 mennowo

Looks like we have a bug. When using:

<DataGrid dataGrid2D:ItemsSource.Array2D="{Binding Array2D}">
    <dataGrid2D:Cell.Template>
        <DataTemplate>
            <TextBlock Text="{Binding StringFormat=E1}" />
        </DataTemplate>
    </dataGrid2D:Cell.Template>
    <dataGrid2D:Cell.EditingTemplate>
        <DataTemplate>
            <TextBox Text="{Binding}" />
        </DataTemplate>
    </dataGrid2D:Cell.EditingTemplate>
</DataGrid>

It throws when entering edit mode.

JohanLarsson avatar Mar 25 '18 11:03 JohanLarsson

Strange! I use this all the time, never had any trouble. Though I always bind to properties on objects in a 2D array, not directly to those items themselves.

On Sun, Mar 25, 2018 at 1:30 PM, Johan Larsson [email protected] wrote:

Looks like we have a bug. When using:

It throws when entering edit mode.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/GuOrg/Gu.Wpf.DataGrid2D/issues/29#issuecomment-375963380, or mute the thread https://github.com/notifications/unsubscribe-auth/ABpzEklKlgkNMkFbPFRcj84cvt1qFyUiks5th3_EgaJpZM4S5epp .

-- To ensure safety and privacy, this email will selfdestruct in 5 seconds. Don't panic!

mennowo avatar Mar 25 '18 12:03 mennowo

Hello! Can anybody help me? I wanna bind 2D int array to DataGrid, but I don't understand how to create TwoWay binding. Now I'm use this code:

<DataGrid Grid.Column="1" Grid.Row="1" x:Name="AutoColumns"
    dataGrid2D:ItemsSource.Array2D="{Binding Path=Data2D, Mode=TwoWay}"
    dataGrid2D:ItemsSource.ColumnHeadersSource="{Binding ColumnHeaders}"
    dataGrid2D:ItemsSource.RowHeadersSource="{Binding RowHeaders}"
    ColumnWidth="50"
    SelectionUnit="Cell"
    IsReadOnly="False"
    IsEnabled="True">
<dataGrid2D:Cell.Template>
<DataTemplate>
    <TextBlock Text="{Binding Path=., StringFormat=X4}" IsEnabled="true"/>
</DataTemplate>
</dataGrid2D:Cell.Template>
    <dataGrid2D:Cell.EditingTemplate>
    <DataTemplate>
        <TextBox Text="{Binding Path=., StringFormat=X4}" />
    </DataTemplate>
</dataGrid2D:Cell.EditingTemplate>
</DataGrid>

Also I'm tried to add an attributes like "Mode=TwoWay, BindsDirectlyToSource=True, UpdateSourceTrigger=LostFocus, NotifyOnSourceUpdated=True" In data templates, but it's do nothing effect. Now it's allow me to entering some numbers in cells, but not save to my array. And one detail - everything work good without templates, but I need them.

odinsacred avatar May 19 '18 15:05 odinsacred

@odinsacred there is no "standard" way, but I suppose you can use converter for your collection (so it will be inner wrapper)

FoggyFinder avatar May 19 '18 17:05 FoggyFinder

@FoggyFinder Maybe we should add an ObservableArray2D<T> that wraps a T[,]? This use case seems pretty common.

JohanLarsson avatar May 19 '18 18:05 JohanLarsson

Maybe we should add an ObservableArray2D<T> that wraps a T[,]?

@JohanLarsson Maybe. I was thinking about how better to handle this case, but all my options has some limitations, so I decided that simple converter is better.

FoggyFinder avatar May 19 '18 19:05 FoggyFinder

for history

https://github.com/GuOrg/Gu.Wpf.DataGrid2D/issues/32

https://github.com/GuOrg/Gu.Wpf.DataGrid2D/issues/33

FoggyFinder avatar May 20 '18 12:05 FoggyFinder