I'm making a custom panel more responsive to design my application.
But something bother me. In my override of MeasureOverride, i call Measure on all childs of my panel.
My childs are grid like the following :
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition MinWidth="150" MaxWidth="220"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition MinWidth="150" MaxWidth="220"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Formulaire 1" Grid.ColumnSpan="4" Grid.Column="1" Style="{DynamicResource Heading1}"/>
<Label Content="Label1" HorizontalAlignment="Left" Grid.Row="1" Grid.Column="1"/>
<Label Content="Label2" HorizontalAlignment="Left" Grid.Row="2" Grid.Column="1"/>
<Label Content="Label3" HorizontalAlignment="Left" Grid.Row="3" Grid.Column="1"/>
<Label Content="Label4" HorizontalAlignment="Left" Grid.Row="4" Grid.Column="1"/>
<Label Content="Label5" HorizontalAlignment="Left" Grid.Row="5" Grid.Column="1"/>
<Label Content="Label6" HorizontalAlignment="Left" Grid.Row="1" Grid.Column="3"/>
<Label Content="Label7" HorizontalAlignment="Left" Grid.Row="2" Grid.Column="3"/>
<Label Content="Label8" HorizontalAlignment="Left" Grid.Row="3" Grid.Column="3"/>
<Label Content="Label9" HorizontalAlignment="Left" Grid.Row="4" Grid.Column="3"/>
<Label Content="Label10" HorizontalAlignment="Left" Grid.Row="5" Grid.Column="3"/>
<Label Content="Message" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="6" Grid.Column="1" />
<TextBox Grid.Column="2" Grid.Row="1"/>
<TextBox Grid.Column="2" Grid.Row="2"/>
<TextBox Grid.Column="2" Grid.Row="3"/>
<TextBox Grid.Column="2" Grid.Row="4"/>
<TextBox Grid.Column="2" Grid.Row="5"/>
<TextBox Grid.Column="4" Grid.Row="1"/>
<TextBox Grid.Column="4" Grid.Row="2"/>
<TextBox Grid.Column="4" Grid.Row="3"/>
<TextBox Grid.Column="4" Grid.Row="4"/>
<TextBox Grid.Column="4" Grid.Row="5"/>
<TextBox Grid.ColumnSpan="3" Grid.Column="2" Grid.Row="6" Height="85" />
</Grid>
This grid have a min desired width of ~407 and a max desired width of ~547. +- 140 based on min and max width of columns.
But while calling Measure on it with an available width (far) superior to the max desired width. The width of his desiredsize remains at his minimal value.
What is not expected to alter the desired size according to the available space?
Except for the two columns with a min and max width, you've specified all rows and columns as "auto". "GridLength.Auto" calculates the width (or height) according to the criteria: The minimum width (or height) that suffices to fit the content.
Therefore, calling Measure() on the grid will return a DesiredSize that's exactly enough to fit the contents of the entire grid. No more, no less. You'll have to include at least one row and column definition using "star-sizing" for it to expand to the available width that you provide.
I decided to inherit from grid and override MeasureOverride to take in concideration star and min/max values to calculate the desired size. My panel work better and it shouldn't have side effect (at least I didn't noticed one yet).
In my opinion, it also respond better in a wrappanel, the child will try fo fit and then after the wrappanel will try to insert the next child in the same line, else make a line break.
I don't realy understand why it's not the default behavior.
For whom interested :
public class CustomGrid : Grid
{
protected override System.Windows.Size MeasureOverride(System.Windows.Size constraint)
{
//I assume Grid.MeasureOverride return the minimum size as desired size
Size MinimumDesiredSize = base.MeasureOverride(constraint);
//The remaining available space provided by the container
double ConstraintWidthRemaining = constraint.Width - MinimumDesiredSize.Width;
//The supposed remaining space if we assume than star columns width equals 0, will be calculated later
double WidthRemaining = ConstraintWidthRemaining;
//The width used in the remaining available space
double WidthUsed = 0;
//The number of column which are star sized
double StarSum = 0;
foreach (ColumnDefinition column in ColumnDefinitions.Where(c => c.Width.IsStar))
{
StarSum += column.Width.Value;
WidthRemaining += column.MinWidth;
}
foreach (ColumnDefinition column in ColumnDefinitions.Where(c => c.Width.IsStar))
{
double Ratio = column.Width.Value / StarSum;
double ColumnWidth = WidthRemaining * Ratio;
if (column.MaxWidth != 0.0)
{
if (ColumnWidth > column.MinWidth)
{
if (ColumnWidth <= column.MaxWidth)
{
WidthUsed += ColumnWidth - column.MinWidth;
}
else
{
WidthUsed += column.MaxWidth - column.MinWidth;
}
}
}
else
{
WidthUsed += ColumnWidth - column.MinWidth;
}
}
MinimumDesiredSize.Width += WidthUsed;
return MinimumDesiredSize;
}
}
Related
I have a Content Page in which I want to show an invoice, for that I have two listviews.
The first one contains the name of the customer, the date and the total cost.
The thing is to get the total cost I have used Shell navigation with parameters and it works fine just not in the listview.
So here is my ViewModel
[QueryProperty(nameof(Total), "total")]
public class InvoiceViewModel : BindableObject
{
string _total;
public string Total
{
get => _total;
set
{
_total = Uri.UnescapeDataString(value ?? string.Empty);
OnPropertyChanged();
}
}
public InvoiceViewModel()
{
_oListOrders = new ObservableCollection<CrOrder>();
GetListCart();
}
private ApiService _apiService = new ApiService();
public List<Invoice> _oListCart = new List<Invoice>();
public ObservableCollection<CrOrder> _oListOrders;
public List<Invoice> ListCart
{
get => _oListCart;
set
{
_oListCart = value;
OnPropertyChanged();
}
}
private async void GetListCart()
{
// call database here
var customerId = Convert.ToInt32(CurrentPropertiesService.GetCustomer());
var customer = await _apiService.GetCustomerById(customerId, CurrentPropertiesService.GetToken());
_oListCart.Add(new Invoice
{
Name = customer.Data.Name,
Date = DateTime.UtcNow,
Total = Convert.ToDecimal(_total),
ListOrders = await GetListOrders()
});
}
private async Task<ObservableCollection<CrOrder>> GetListOrders()
{
// call database here
var cartId = Convert.ToInt32(CurrentPropertiesService.GetCart());
var orders = await _apiService.GetOrdersByCart(cartId, CurrentPropertiesService.GetToken());
ObservableCollection<CrOrder> collection = new ObservableCollection<CrOrder>(orders.Data);
return collection;
}
}
Here is what I have in my View
<ContentPage.Content>
<StackLayout BackgroundColor="#A7A7A7">
<Label Text="{Binding Total}" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"></Label>
<ListView x:Name="ListViewCart" ItemsSource="{Binding ListCart}" HasUnevenRows="True" IsPullToRefreshEnabled="False" >
<ListView.ItemTemplate>
<DataTemplate x:DataType="model:Invoice">
<ViewCell>
<Frame HasShadow="True" Margin="2" BorderColor="Gray">
<Grid Margin="0" HorizontalOptions="FillAndExpand" VerticalOptions="Center" HeightRequest="150" RowSpacing="0" ColumnSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Text="Nombre del Cliente:" VerticalOptions="Start"/>
<Label Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Text="{Binding Name}" VerticalOptions="Start"/>
<Label Grid.Row="1" Grid.Column="0" Text="Fecha Compra:" VerticalOptions="Start"/>
<Label Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" Text="{Binding Date}" VerticalOptions="Start"/>
<Label Grid.Row="2" Grid.Column="0" Text="Monto Total:" VerticalOptions="Start"/>
<Label Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Text="{Binding Total, StringFormat='{0:N2}€'}" VerticalOptions="Start"/>
<Label Grid.Row="3" Grid.ColumnSpan="3" Text="Detalle Compra" VerticalOptions="Start"/>
<BoxView Grid.Row="4" Grid.ColumnSpan="3" Color="Gray" HeightRequest="2" HorizontalOptions="Fill" />
<Label Grid.Row="5" Grid.Column="0" Text="Nombre" VerticalOptions="Start" TextColor="#9C2424"/>
<Label Grid.Row="5" Grid.Column="1" Text="Monto" VerticalOptions="Start" TextColor="#9C2424"/>
<Label Grid.Row="5" Grid.Column="2" Text="Cantidad" VerticalOptions="Start" TextColor="#9C2424"/>
<StackLayout Grid.Row="6" Grid.ColumnSpan="3" Margin="0" Padding="0">
<ListView x:Name="ListViewOrders" ItemsSource="{Binding ListOrders}" HasUnevenRows="True" IsPullToRefreshEnabled="False" >
<ListView.ItemTemplate>
<DataTemplate x:DataType="model:CrOrder">
<ViewCell IsEnabled="False">
<Grid RowSpacing="0" ColumnSpacing="0" Margin="0" MinimumHeightRequest="50">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Text="{Binding Reference}" TextColor="Black" VerticalOptions="Center" FontSize="12" />
<Label Grid.Row="0" Grid.Column="1" Text="{Binding Price, StringFormat='{0:N2}€'}" TextColor="Black" VerticalOptions="End" FontSize="12" />
<Label Grid.Row="0" Grid.Column="2" Text="{Binding Quantity}" TextColor="Black" VerticalOptions="End" FontSize="12"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>...
And on my ContentPage I don't have anything
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class InvoicePage : ContentPage
{
public InvoicePage()
{
InitializeComponent();
//BindingContext = new InvoiceViewModel();
}
}
So on my View I have put a label to check what I thought was happening. So the label shows right the total but when I use the ListView binging it doesn't work I don't know why it is null there.
As you can see the label works fine but where it sais "Monto Total" it shows nothing. Please help I don't know what is going on. Thanks.
EDIT
I tried naming the Total property different and then when I add my Invoice entity to my list I do this
Total = Convert.ToDecimal(TotalCart),
But it isn't working eitherway. I don't know why the first time it returns the value fine but the second it doesn't.
After debbuging I have realized when getting the total property that the first time when GetListCart is being called the value is null and the second time, when the label text is set it returns the correct value. Why is this happening?
I have to pass the Text={Binding Id}of textBlock idName from a frame to another frame. the text is an Id from an SQLite database. I have an Listview.ItemTemplate that define the item
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="Auto" Margin="0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="12,0,0,0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="idName" Text="{Binding Id}" FontSize="12" VerticalAlignment="Center" Grid.Column="0" Margin="5,0,12,0"/>
<RelativePanel Grid.Column="1">
<TextBlock x:Name="titleBlock" Text="{Binding Title}" FontSize="25" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<TextBlock x:Name="directorLabel" Text="REGISTA:" FontSize="20" RelativePanel.Below="titleBlock" FontWeight="Light"/>
<TextBlock x:Name="directorBlock" Text="{Binding Director}" FontSize="20" RelativePanel.Below="titleBlock" RelativePanel.RightOf="directorLabel"/>
<TextBlock x:Name="yearLabel" Text="ANNO:" FontSize="20" FontWeight="Light" RelativePanel.RightOf="directorBlock" Margin="12,0,0,0" RelativePanel.Below="titleBlock"/>
<TextBlock x:Name="yearBlock" Text="{Binding Year}" FontSize="20" RelativePanel.Below="titleBlock" RelativePanel.RightOf="yearLabel"/>
</RelativePanel>
</Grid>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
I use in the Code Behind this:
this.Frame.Navigate(typeof(FilmInfo), idName.Text);
but idName.Text is an ItemTemplate.
How can I do that?
I'm assuming the item must somehow be selected in the ListView in order to take action on it... if so, you can use the item directly.
YourClassName selectedFilm = YourListView.SelectedItem as YourClassName;
If(selectedFilm != null)
{
this.Frame.Navigate(typeof(FilmInfo), selectedFilm.Id);
}
UPDATE after comment
OK... if you're using the item click event, you can do the same thing...
private void ItemClickEvent(object sender, ItemClickEventArgs e)
{
YourClassName selectedFilm = e.ClickedItem as YourClassName;
if(selectedFilm != null)
{
this.Frame.Navigate(typeof(FilmInfo), selectedFilm.Id);
}
}
I want to assign the values of the findFamily object to the different TextBox(s) i tried the following code but it's not working would you please suggest me a better way. Thanks in advance.
private void Search_Click(object sender, RoutedEventArgs e)
{
if (SearchFamilyMemberId.Text.Trim() != "")
{
SITDataDataContext con = new SITDataDataContext();
List<Family> findFamily = (from s in con.Families where s.FamilyMemberId.Equals(SearchFamilyMemberId.Text.Trim()) select s).ToList();
if (findFamily.Any())
{
FamilyMemberId.Text = findFamily[0];
FirstName.Text = findFamily[1];
LastName.Text = findFamily[2];
if (findFamily[3]=="Male")
{
Male.IsChecked = true;
}
else
{
Female.IsChecked = true;
}
Phone.Text = findFamily[4];
Address.Text = findFamily[5];
}
else
{
MessageBox.Show("Family Id not found!");
}
}
else
{
MessageBox.Show("Invalid Id!");
}
}
here is my xamal code
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="1" Grid.Column="0" Content="Family Member ID:"/>
<Label Grid.Row="2" Grid.Column="0" Content="First Name:"/>
<Label Grid.Row="3" Grid.Column="0" Content="Last Name:"/>
<Label Grid.Row="4" Grid.Column="0" Content="Gender:"/>
<Label Grid.Row="5" Grid.Column="0" Content="Phone:"/>
<Label Grid.Row="6" Grid.Column="0" Content="Address:"/>
<CheckBox Name="ColonyResident" Content="Colony Resident" Grid.Row="0" Grid.Column="0" Margin="5" Checked="ColonyResident_Checked" Unchecked="ColonyResident_Unchecked"/>
<TextBox Name="SearchFamilyMemberId" IsEnabled="False" SelectionChanged="FamilyMemberId_SelectionChanged" Grid.Row="0" Grid.Column="1" Margin="3"/>
<TextBox Name="FamilyMemberId" IsEnabled="False" Grid.Row="1" Grid.Column="1" Margin="3" Grid.ColumnSpan="2"/>
<TextBox Name="FirstName" Grid.Row="2" Grid.Column="1" Margin="3" Grid.ColumnSpan="2"/>
<TextBox Name="LastName" Grid.Row="3" Grid.Column="1" Margin="3" Grid.ColumnSpan="2"/>
<RadioButton Name="Male" Grid.Row="4" Grid.Column="1" Margin="3" Content="Male" />
<RadioButton Name="Female" Grid.Row="4" Grid.Column="2" Margin="3" Content="Female" />
<TextBox Name="Phone" Grid.Row="5" Grid.Column="1" Margin="3" Grid.ColumnSpan="2"/>
<TextBox Name="Address" Grid.Row="6" Grid.Column="1" Margin="3" Grid.ColumnSpan="2" TextWrapping="Wrap"/>
<Button Name="Search" IsEnabled="False" Grid.Row="0" Grid.Column="2" Margin="3" MinWidth="100" MinHeight="25" HorizontalAlignment="Center" Content="Search" Click="Search_Click"/>
<Button IsDefault="True" Grid.Row="7" Grid.Column="1" Margin="3" MinWidth="100" MinHeight="25" HorizontalAlignment="Center" Content="Add" Click="Add_Click"/>
<Button Grid.Row="7" Grid.Column="2" Margin="3" MinWidth="100" MinHeight="25" HorizontalAlignment="Center" Content="Clear" Click="Clear_Click"/>
</Grid>
Why don't you use data binding?
For each of the text boxes that you have, bind your TextBox.Text to its corresponding property in the view model, something like this:
<TextBox Text={Binding FirstName} />
Then, assign your FirstName, LastName...etc. properties to values and raise INotifyPropertyChanged.PropertyChanged for each of the properties (your view model should implement INotifyPropertyChanged) and your view (i.e. UI) should get updated.
I don't agree with any of the answers posted here. The question doesn't seem to be correct.
If you have a list of Family members. Then how can you show it as a single item. How do you know which item you want to display.
Hence my suggestion is to use a listbox and using data binding, create a view to display the current selected Family member's data in that view.
use foreach loop through list as:
foreach(var a in findFamily)
{
txtbox.text=a[0].tostring();
txtbox2.text=a[1].tostring();
}
or use:
txtbox.text = findFamily.Select(a => a[0].ToString()).FirstOrDefault().ToString();
My problem is that my items won't add to the list. I try to add 3 texts and one image location to the list. I try everything but I couldn't do it.
XAML code
<ListBox Name="mylistbox" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="6" Grid.RowSpan="3">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Name="s1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition Height="100"/>
<RowDefinition Height="30"/>
<RowDefinition Height="20/"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding naslov}" Tag="{Binding broj}" FontSize="32" Foreground="White" HorizontalAlignment="Center" TextWrapping="Wrap" Grid.Row="1" Grid.Column="2" />
<TextBlock Text="{Binding datum}" Foreground="White" HorizontalAlignment="Right" VerticalAlignment="Center" TextWrapping="Wrap" Grid.Row="2" Grid.Column="2"/>
<Image Source="{Binding slika}" Grid.Row="1" Grid.Column="1" Grid.RowSpan="2"/>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
C# code
for (int i = 1; i < datum.Count; ++i)
{
podatak _podatak = new podatak();
_podatak.naslov = naslovi[i];
_podatak.datum = datum[i];
_podatak.broj = Convert.ToString(broj);
_podatak.slika = "http://hsin.hr/images/logo.gif";
mylistbox.Items.Add(_podatak);
}
I didn't test, but I think you are missing one detail, and doing a little mistake.
First: you need to bind a List to a ListBox. So, I believe you should do something like this:
List<podatak> myList = new List<podatak>();
for (int i = 1; i < datum.Count; ++i)
{
podatak _podatak = new podatak();
_podatak.naslov = naslovi[i];
_podatak.datum = datum[i];
_podatak.broj = Convert.ToString(broj);
_podatak.slika = "http://hsin.hr/images/logo.gif";
myList.Add(_podatak);
}
mylistbox.ItemsSource = myList;
And Second: add this on xaml:
<ListBox Name="mylistbox" ItemsSource="{Binding}" ...
Correcting:
As commented, doesn't need change anything on your XAML code.
My mistake.
I have a XAML with 2 columns in a Grid and I have a button that when I click it, in the code behind, I set the visibility to collapse, and want to resize the other half of the screen to try to take up the whole screen. The collapsing part works, and the RHS then shifts over to the LHS, but it does not take up the entire screen. I tried using both the Auto and Star to resize in HidePlots, but it never takes the full screen. I thought if I collapsed the LHS, and set the column to * for the RHS, it would take up the whole screen. Any thoughts? Thanks.
Here's some code to make it more clear:
<Grid Grid.Row="1" x:Name="ExpandableGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="1.5*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" x:Name="TableGrid">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<GroupBox Grid.Row="0" Grid.Column="0" x:Name="SampleViewGroupBox" Header="SampleView" HorizontalAlignment="Stretch" FontFamily="Arial" FontSize="12" Margin="5,0,5,0" >
<ContentControl Content="{Binding LayoutManager.SampleView}" Height="Auto" Width="Auto"/>
</GroupBox>
<Button x:Name="TableButton" HorizontalAlignment="Right" Content="Button" Width="15" Height="15" VerticalAlignment="Top" Margin="0,0,-2,0" Click="MaxButton_Click" Grid.Column="0" Grid.Row="0"/>
</Grid>
<Grid Grid.Column="1" x:Name="BaseViewGrid">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<GroupBox Grid.RowSpan="2" Grid.Column="1" Name="BaseViewGroupBox" Header="PLOTS" Margin="5,0,5,0" >
<ContentControl Content="{Binding LayoutManager.ConsensusView}" Height="Auto" Width="Auto" />
</GroupBox>
</Grid>
</Grid>
private void MaxButton_Click(object sender, RoutedEventArgs e)
{
UIElement senderElement = (UIElement)sender;
if (_tableMinimized)
{
HideTables(false);
_tableMinimized = false;
((Button)senderElement).Style = (Style)FindResource("DashboardDetailsButton");
}
else
{
HideTables(true);
_tableMinimized = true;
((Button)senderElement).Style = (Style)FindResource("DashboardDetailsButtonReverse");
}
}
private void HideTables(bool hide)
{
if (hide)
{
foreach (UIElement child in TableGrid.Children)
child.Visibility = Visibility.Collapsed;
for (int i = 0; i < ExpandableGrid.ColumnDefinitions.Count; i++)
ExpandableGrid.ColumnDefinitions[i].Width = GridLength.Auto;
ExpandableGrid.ColumnDefinitions[1].MinWidth = 500;
for (int i = 0; i < ExpandableGrid.RowDefinitions.Count; i++)
ExpandableGrid.RowDefinitions[i].Height = GridLength.Auto;
TableButton.Visibility = Visibility.Visible;
}
else
{
foreach (UIElement child in TableGrid.Children)
child.Visibility = Visibility.Visible;
for (int i = 0; i < ExpandableGrid.ColumnDefinitions.Count; i++)
ExpandableGrid.ColumnDefinitions[i].Width = new GridLength(1, GridUnitType.Star);
for (int i = 0; i < ExpandableGrid.RowDefinitions.Count; i++)
ExpandableGrid.RowDefinitions[i].Height = new GridLength(1, GridUnitType.Star);
}
}
Edit: I tried to also change one line to:
ExpandableGrid.ColumnDefinitions[1].MinWidth = System.Windows.SystemParameters.PrimaryScreenWidth-20;
instead of the hard-coded 500 value, it looks correct. However, if I try to click the button again to revert back to normal, the RHS takes up the bulk of the screen without getting back to its original position.
Your current column definition says to make Column B equal to 1.5 times the size of Column A, so even if ColumnB's content is hidden, the column will still take up 3/5 of the screen.
Change it so the column that collapses has a Width="Auto", and set it's Content's Width equal to whatever size it should be when it's expanded. If you want to keep the 1.5* default width, I'd recommend using something like a MathConverter to figure out what size it should be based on the parent Grid's width. I have the code for one posted here
<Grid x:Name="ParentGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid x:Name="RHS" Grid.Column="0" />
<!-- Collapse this Grid -->
<Grid x:Name="LHS" Grid.Column="1"
Width="{Binding ElementName=ParentGrid, Path=ActualWidth,
Converter={StaticResource MathConverter},
ConverterParameter=((#VALUE/5)*3)}" />
</Grid>
You need to set column 0 to be whatever you desire (Auto, 150, etc...) and set column 1 to be *.
It looks like your Grid is also within a Grid, so the parent's behavior also has to be taken into account.