question

FanhuaKong-4325 avatar image
0 Votes"
FanhuaKong-4325 asked ·

DataGrid with data won't fill parent's width

Hi,
I met a very weird thing. I have a DataGrid in my WPF program. The overall setting for the DataGrid is as following:

 <Grid>
         <Grid.RowDefinitions>
             <RowDefinition Height="*" />
             <RowDefinition Height="Auto" />
         </Grid.RowDefinitions>
         <!--DataGrid element-->
         <DataGrid
             Grid.Row="0"
             x:Name="LoadDataGrid"
             ItemsSource="{Binding DataGridSource, UpdateSourceTrigger=PropertyChanged}" 
             AutoGenerateColumns="False"
             CanUserAddRows="False"
             CanUserSortColumns="False"
             CanUserDeleteRows="False"
             CanUserReorderColumns="False"
             GridLinesVisibility="All"
             HorizontalScrollBarVisibility="Auto"
             VerticalScrollBarVisibility="Visible"
             HorizontalAlignment="Center"
             RowHeaderWidth="0"
             BorderBrush="Black"
             BorderThickness="1"
             Background="{StaticResource CustomPureWhiteBrush}"
             SelectedIndex="{Binding CurrentRowIndex, Mode=TwoWay}">
             <DataGrid.Columns>
             ...
             </DataGrid.Columns>
             </DataGrid>

And the related code in ViewModels are:

 /// <summary>
         /// Load DataGridSource automatically if data file is saved in the same directory with the dwg drawing.
         /// If it doesn't exist, all a new empty item to DataGridSource
         /// </summary>
         protected override void DataGridSourceLoaded()
         {
             // Check if the data file exists
             bool IsDataSourceExists = HX_FileOperations.IsFileExistsInCurrentDirectory("低压配电回路设计.HX");
    
             // If it doesn't exist, add an initial member to DataGridSource
             if (!IsDataSourceExists)
             {
                 // Add a new item to the GridDataSource
                 DataGridSource.Add(new LoadItemViewModel()
                 {
                     Id = DataGridSource.Count + 1,
                 });
             }
             // If it exists, then read data to DataGridSource
             else
             {
                 DataGridSource.Clear();
                 List<Loads> loadsList = FileOperation.ReadBinaryDataFromCurrentDirectory("低压配电回路设计.HX") as List<Loads>;
                 for (int i = 0; i < loadsList.Count; i++)
                 {
                     DataGridSource.Add(new LoadItemViewModel()
                     {
                         Id = i + 1,
                         TransformerNumber = loadsList[i].TransformerNumber,
                         ELVCabinetNumber = loadsList[i].ELVCabinetNumber,
                         CircuitNumber = loadsList[i].CircuitNumber,
                         UnitType = loadsList[i].UnitType,
                         SeperationHeight = loadsList[i].SeperationHeight,
                         EquiptmentNumber = loadsList[i].EquiptmentNumber,
                         EquiptmentFunction = loadsList[i].EquiptmentFunction,
                         LoadsType = loadsList[i].LoadsType,
                         LoadLevel = loadsList[i].LoadsLevel,
                         ApplicationRange = loadsList[i].ApplicationRange,
                         DieselConnection = loadsList[i].DieselConnection,
                         EquiptPowerP = loadsList[i].EquiptPowerP,
                         EquiptPowerX = loadsList[i].EquiptPowerX,
                         SimultaneousRatioP = loadsList[i].SimultaneousRatioP,
                         SimultaneousRatioX = loadsList[i].SimultaneousRatioX,
                         PowerRatioP = loadsList[i].PowerRatioP,
                         PowerRatioX = loadsList[i].PowerRatioX,
                         TanP = loadsList[i].TanP,
                         TanX = loadsList[i].TanX,
                         PcP = loadsList[i].PcP,
                         PcX = loadsList[i].PcX,
                         QcP = loadsList[i].QcP,
                         QcX = loadsList[i].QcX,
                         ScP = loadsList[i].ScP,
                         ScX = loadsList[i].ScX,
                         IcP = loadsList[i].IcP,
                         IcX = loadsList[i].IcX,
                     });
                 }
             }
         }

When it shows less than 10 data items, the width of DataGrid is just as big as Grid. But when it shows more data items, the width of DataGrid is just one fifth the width of the Grid. All columns are even narrow than its contents.
Just like the below picture shows:
6711-a.png

I've tested lots of possibilities. And I found that no matter how much items the DataGrid is showing. It starts with a very thin table and then(maybe wait all data is loaded) becomes as wider as its container. And when the data item are much more, it takes a while to load, and I think that blocks the DataGrid to adapt to its container.

I tried to manually scales the window to a very small one(just cover lots area of the DataGrid) and then maximize the window, the DataGrid turns out to displaying Correct as following:
6721-g.png

So, Is it because of the data loading thing? If it is, how to solve it? I've tried put the load data into the OnLoad events so all components can be initialized first, but no luck with that.



windows-wpf
a.png (66.4 KiB)
g.png (208.4 KiB)
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

LloydSheen-3317 avatar image
0 Votes"
LloydSheen-3317 answered ·

Looking at the full XAML I have a suggestion. The TemplateColumns have widths defined as for many. Try using Auto and see if that make a difference. It most likely won't be what you want but it will show if that is the problem. If it is the problem then you would have to use something rather than to define the widths.

· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi, thanks for your reply.
Replacing all "*" with "Auto" works. But it makes difficult to manage the column width.
And I've tried another to make it work. In the constructor of the corresponding view model, I just add a new empty item to the ItemSource instead of loading existing data source. And then, in the Loaded event, I update the ItemSource. It works as well.

0 Votes 0 ·
LloydSheen-3317 avatar image
0 Votes"
LloydSheen-3317 answered ·

Without seeing any XAML it is impossible to help. Please share the XAML so that we might helop.

· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Sorry for that. I posted it in a rush. And I've tried some other solutions and found more details. I've updated the post. Thanks a lot.

0 Votes 0 ·
LloydSheen-3317 avatar image
0 Votes"
LloydSheen-3317 answered ·

Still without XAML anything would be a total guess.

· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Ok. As to the forum can only upload xml file. I've uploaded XAML and a simple version of the application on OneDrive for you to test.

The XAML file download link:
s!AvHkfcqC8dwrgqlGCCkfjoNwrTz1Zg

The simplified application download link:
s!AvHkfcqC8dwrgqlDssdgisuUUbU5Gw

The data file to run the application link:
https://1drv.ms/u/s!AvHkfcqC8dwrgqlCJaZsxhDyZlQEnQ?e=0ZCTy9

Before run the application, please put the data file(SourceFile folder) into C:\Program Files(The full path should be C:\Program Files\SourceFile). And when you run the application, please click "ClickToTest" button. Be sure to maximize the window before you click to get the same result. The related view is in Pages/LoadPage.xaml and the corresponding ViewModel is in ViewModels/LoadViewModel.cs. Thanks a lot.


0 Votes 0 ·
LucaCorradi-0010 avatar image
0 Votes"
LucaCorradi-0010 answered ·

Did you try to remove HorizontalAlignment="Center" property?

By default, the DataGrid's HorizontalAlignment value is set to "Stretch" (as well as VerticalAlignment) that means to stretch the horizontal/vertical content size to fit the parent.

If you, correctly, embedded the DataGrid inside a full width Grid, you don't need to do anything else.
HorizontalAlignment="Center" would set the DataGrid content ad the minimum to fit its content, then center it.

· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi, thanks for your reply. Unfortunately, If I remove HorizontalAlignment = "center", the width of the DataGrid still wont't fit and a new column is added to fill the window even though I've already set AutoGenerateColumns="False". The result is like followings:

0 Votes 0 ·