3

I'm trying to use GridControl from DevExpress but I can't do the same thing I usually do in ListView with a GridView View.

I did both aproach. Using DisplayMemberBinding and CellTemplate. Both show nothing. Code below (I removed some columns):

<dxg:GridControl ItemsSource="{Binding}" Name="gridControl1">
    <dxg:GridControl.Columns>
        <dxg:GridColumn Header="Teste" DisplayMemberBinding="{Binding DataNascimento}"/>
        <dxg:GridColumn Header="Nome">
            <dxg:GridColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Nome}"/>
                </DataTemplate>
            </dxg:GridColumn.CellTemplate>
        </dxg:GridColumn>
    </dxg:GridControl.Columns>
    <dxg:GridControl.View>
        <dxg:TableView Name="tableView1" AutoWidth="True" />
    </dxg:GridControl.View>
</dxg:GridControl>

It is shown like this image:

Grid with bound data but shown nothing

You can see my columns but no data. I bound 3 items and it shows 3 rows. The data itself is bound but looks like the template was not shown.

I tried the same aproach of this question but not work for me. My class have INotifyPropertyChanged and I used an ObservableCollection<T> before bindind to the GridControl. The only way it works is if I remove almost all code and change the AutoPopulateColumns to True. But in some cases I want a custom format and cannot achieve with this option.

Edit1: I did this in Design mode and works:

            <dxg:GridColumn FieldName="DataNascimento" Name="gridColumn3">
                <dxg:GridColumn.EditSettings>
                    <dxe:TextEditSettings DisplayFormat="{}{0:dd/MM/yyyy HH:mm:ss}" />
                </dxg:GridColumn.EditSettings>
            </dxg:GridColumn>

Edit2: Tried the same aproach @blindmeis suggests with grid and it works like I spected:

<DataGrid AutoGenerateColumns="False" Grid.Row="2" ItemsSource="{Binding}">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding DataNascimento}" Header="Nascimento" />
        <DataGridTextColumn Binding="{Binding Nome}" Header="Header" />
        <DataGridTemplateColumn Header="Teste">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBox Text="{Binding Nome}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

Looks like this aproach works in both ListView and DataGrid. Unfortunately GridControl behaves different.

Using <dxg:GridColumn.EditSettings> is the correct way?

Community
  • 1
  • 1
Vitor Canova
  • 3,918
  • 5
  • 31
  • 55
  • 1
    have you tried your 1st code with the built in DataGrid form .Net4.0? i use it all the way and it works. – blindmeis Jul 03 '12 at 06:48
  • @blindmeis Just tried. I can use almost the same aproach. I can use `DataGridTemplateColumn` and provide what I want. But I really need many features provided by `GridControl`. Thanks. Just learned that `DataGrid` has `DataGridTemplateColumn`. – Vitor Canova Jul 03 '12 at 13:12

3 Answers3

3

It end up in a more complicated problem.

As I had mention above in my edit TextEditSettings did what I wanted in that particularly case. But as soon as I improved the code some bugs started to appear.

The problem I faced after that is mentioned here at the official DevExpress forum and I'm summarizing below:

The real problem

I was using a base class for some reports and in those grids I was using theirs derivated classes.

The solution I had mention in my question works in a regular nom derivated class but I soon as I started to use properties from the base class and the derivated class some strange behavior started to happen.

By using the TextEditSettings with FieldName I could format the data and show its summary for properties in the derivated class but for properties in the base class it did not work.

So I changed to DisplayMemberBinding and it worked with all properties but the summary stopped work.

The solution

To make format option available for properties from your class and properties inherited and to make summary work properly you must use like this:

Side Note: Don't know if all those properties in the TableView are really necessary but since this control is very sensitive to changes with them I keep them all just to make clear what worked for me.

<dxg:GridControl ItemsSource="{Binding MyObservableCollection}">
    <dxg:GridControl.Columns>
        <dxg:GridColumn DisplayMemberBinding="{Binding Percent}"
                        FieldName="Percent"
                        Header="%">
            <dxg:GridColumn.EditSettings>
                <dxe:TextEditSettings DisplayFormat="F2" />
            </dxg:GridColumn.EditSettings>
        </dxg:GridColumn>
    </dxg:GridControl.Columns>
    <dxg:GridControl.View>
        <dxg:TableView AllowSorting="False"
                       ShowTotalSummary="True"
                       FilterEditorShowOperandTypeIcon="True"
                       NavigationStyle="Row"
                       MultiSelectMode="None"
                       AllowColumnFiltering="False"
                       AllowDateTimeGroupIntervalMenu="False"
                       AllowEditing="False"
                       AllowFilterEditor="False"
                       AllowGrouping="False"
                       ClipboardCopyAllowed="False"
                       ShowGroupPanel="False" />
    </dxg:GridControl.View>
    <dxg:GridControl.TotalSummary>
        <dxg:GridSummaryItem FieldName="Percent"
                             DisplayFormat="F2"
                             SummaryType="Sum" />
    </dxg:GridControl.TotalSummary>
</dxg:GridControl>

In this case it will work in the Percentproperty that was inherited. The DisplayMemberBinding will make it work for the TextEditSettings and the FieldName in the GridColumn is used to make summary get that property in GridSummaryItem.

Vitor Canova
  • 3,918
  • 5
  • 31
  • 55
1

i was just needing to format a text, but apparently the DevExpress GridControl, doesn't support StringFormat. After various intents, i was able to manage the formatting.

I populate my grid using an ObservableCollection. The columns are:

Price, datatype double, i.e.: 15

Symbol, datatype string, i.e.: US$

and the format i was expecting: US$ 15.00

This is the way i usually do with a regular DataGrid

<DataGridTextColumn  Header="Price" IsReadOnly="True">
    <DataGridTextColumn.Binding>
        <MultiBinding StringFormat="{}{0} {1:#.00}">
            <Binding Path="Symbol" />
            <Binding Path="Price" />
        </MultiBinding>
    </DataGridTextColumn.Binding>
</DataGridTextColumn>

Here is how i do it. Note that in "Binding Path" the field needs to be preceded by Data. and has to have RelativeSource="{RelativeSource Self}", or it won't work.

<dxg:GridColumn Header="Price" FieldName="Price">
    <dxg:GridColumn.DisplayMemberBinding>
        <MultiBinding Converter="{StaticResource stringConcatenator}">
            <Binding Source="{}{0} {1:#.00}"/>                                                    
            <Binding Path="Data.Symbol" RelativeSource="{RelativeSource Self}" />
            <Binding Path="Data.Price" RelativeSource="{RelativeSource Self}"/>
        </MultiBinding>
    </dxg:GridColumn.DisplayMemberBinding>                                      
</dxg:GridColumn>

And here the converter:

public class StringConcatenator : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        //the first parameter is the format, and the consequent parameters are the values
        return string.Format(values[0].ToString(), values.Skip(1).Take(values.Length - 1).ToArray());
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        return new string[] { };
    }
}
jrivam
  • 1,081
  • 7
  • 12
0

If you are binding your datagrid with observable collection from your view model and if your observable collection have DataNascimento and Nome as two fields then you do not have to bind them again like you did. You can directly give fieldname and it will populate the columns with values from your observable collection.

You can do something like this:

<DataGrid AutoGenerateColumns="False" Grid.Row="2" ItemsSource="{Binding YOUR_OBSERVABLE_COLLECTION}">
<DataGrid.Columns>
    <DataGridTextColumn FieldName="DataNascimento" Header="Nascimento" />
    <DataGridTextColumn FieldName="Nome" Header="Header" />
    <DataGridTemplateColumn Header="Teste">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <TextBox Text="{Binding Nome}"/>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
</DataGrid.Columns>

sunil5715
  • 260
  • 1
  • 3
  • 12
  • Actually you code looks correct. And you wrote like I expected. But You missed one point: I'm using a DevExpress GridControl. You can see that my fist example is equivalent as yours. Many things in this control does not behaves like a normal WPF control. ;) – Vitor Canova Mar 11 '13 at 22:50