I have a 4 row, 1 column Grid wrapped in a ScrollViewer.
The rows are Treeviews that are bound to hierarchy (nested Lists) of objects.
I'm using a HierarchicalDataTemplate to lay out the TreeViewItem nodes and their children / ItemTemplates.
My problems is that whenever I expand the TreeViewItems, the vertical scrollbar is not showing up.
Oddly enough, the horizontal scrollbar will show up when I expand out an AccordionItem that is part of the child nodes.
I have tried creating an event handler that calls UpdateLayout() whenever a TreeViewItem is expanded, but that's not causing the scrollbar to appear. I have tried calling UpdateLayout() against the TreeView, the Grid, and the ScrollViewer as well.
The answer to this became painfully obvious after some experimentation.
Specifying the Height property for the ScrollViewer was the missing piece that made everything work as it would be expected.
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
Height="350"> <!-- THIS was the missing piece!! -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Controls:TreeView Grid.Row="0" ItemsSource="{Binding ListOne}"
ItemTemplate="{StaticResource ListOneTemplate}" >
</Controls:TreeView>
<Controls:TreeView Grid.Row="1" ItemsSource="{Binding ListTwo}"
ItemTemplate="{StaticResource ListTwoTemplate}" >
</Controls:TreeView>
</Grid>
</ScrollViewer>
FWIW, I tried a number of other solutions including setting heights and maxheights for the Grid, GridRows, and TreeView. I also tried creating an event to set the height of the scrollviewer whenever the grid height changed, and an event that fired off cascading UpdateLayouts() whenever a tree view item changed.
Setting the height on the ScrollViewer was the only approach I found that made everything work as expected.
Also, you can set the row definition:
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/> // tree view position
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
The treeview will take the free space of the screen, showing scrollbars if necessary.
Related
the environment:
Visual Studio 17.4.3
Dotnet 7 v101
Mvvm Community 8.0
When I try on windows application to use a slider in a list view the slider doesn't get binded correctly to the items of the list view (at least my uneducated guess). The slider looks to be in de default state.
i have a model for changeable properties like this:
public class ChangeableProperty {
public int MinValue {get;set;}
public int MaxValue {get;set;}
public int Value {get;set;}
}
[ObservableProperty]
IEnumerable<ChangeableProperty> dynamicProperties;`
I get them from the backend and try to show them in the Maui App using Mvvm Toolkit.
The ListView is showing and in the first column I added some labels to show the values.
When using the slider the values are not used.
The source is
<ListView ItemsSource="{Binding DynamicProperties, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="imaging:ChangeableProperty">
<ViewCell>
<Grid Padding="10">
<Grid.RowDefinitions>
<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="50*"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0"
Grid.Column="0"
Text="{Binding Name}"
FontAttributes="Bold"/>
<Label Grid.Row="1"
Grid.Column="0"
Text="{Binding Value, Mode=OneWay}"
FontAttributes="Italic"/>
<Label Grid.Row="2"
Grid.Column="0"
Text="Min"
FontAttributes="Bold"/>
<Label Grid.Row="3"
Grid.Column="0"
Text="{Binding StartValue, Mode=OneWay}"
FontAttributes="Italic"/>
<Label Grid.Row="4"
Grid.Column="0"
Text="Max"
FontAttributes="Bold"/>
<Label Grid.Row="5"
Grid.Column="0"
Text="{Binding EndValue, Mode=OneWay}"
FontAttributes="Italic"/>
<Slider Grid.Column="1"
Grid.Row="0"
Grid.RowSpan="4"
x:Class="ChangeableProperty"
Minimum="{Binding MinValue}"
Maximum="{Binding MaxValue}"
VerticalOptions="Center"
Value="{Binding Value, Converter{StaticResource DoubleToIntConverter}}"
MinimumTrackColor="Red"
MaximumTrackColor="Blue"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
<ListView>
The slider appears to have the default settings. Is it possible to have the changed in a property notified? The demos I saw are related to showing only the list (so when entries available show them) but not for editing using a slider.
Is this a known issue or is it not possible to use a slider in a list view like this?
Kind regards
Yes, this issue can be replicated when setting binding to the Slider. The binding value of the Slider fails to change when using binding. This issue looks similar to an existing one in Github:Setting Slider.Maximum or Slider.Minimum resets binding of Slider.Value. You can follow up there.
Also, you can raise a new issue on Github via this link:https://github.com/dotnet/maui/issues/new/choose
I have a ListView with the default SeparatorVisibility. My Android project shows the Separator if there are elements in the ItemsSource and stops showing it below the last element. It's the result I want for my iOS project.
However, in my iOS project the screen is full of Separators no matter how many elements I have, even if I have no elements or only one, the Separators still being there.
Could someone give me a reason and how to fix it please? Thanks.
I think you can take a look to this post
these are some tips
First disable the default separator, this is done by adding following property to the ListView XAML
SeparatorColor="Transparent"
After this, wrap the complete ViewCell content inside a double StackLayout! I know this sounds like overkill but this way you’ll not run into any BoxView issues regarding margins inside the ViewCell… or other stuff.
The first StackLayout should have a BackgroundColor set to the colour you want your separator to be, the second StackLayout should have the same BackgroundColor as the rest of the container it is in… in our example the page and that is set to white. Be sure to also add a Margin to the bottom of this second StackLayout because that will represent the thickness of our separator!
I think you can play with this "Margin"... when your data is empty, remove the margin so you should not have the separator
<ListView x:Name="SeparatorListView"
SeparatorColor="Transparent"
ItemsSource="{Binding Persons}"
Margin="0,20,0,0"
RowHeight="60"
HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
BackgroundColor="White"
Grid.Row="1">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell IsEnabled="false">
<StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"
BackgroundColor="Black">
<StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"
BackgroundColor="White"
Margin="0,0,0,0.4">
<StackLayout VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand" Spacing="0">
<Label Text="{Binding FullName}" TextColor="Maroon" VerticalOptions="CenterAndExpand" Margin="20,0,20,0" />
<Label Text="{Binding Profession}" TextColor="Maroon" VerticalOptions="CenterAndExpand" Margin="20,0,20,0" />
</StackLayout>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
With that in place, you’ll get the same visual result as the preview image at the top right of this blog post.
As a bonus, you could omit one of the StackLayouts IF your page has a background color other than white. Because if this is the case, you can use that color as the separator color by playing with transparency inside the ListView.
Example of this, note will only work if the page itself also has a BackgroundColor set to Olive!
<ListView x:Name="SeparatorListView"
SeparatorColor="Transparent"
ItemsSource="{Binding Persons}"
Margin="0,20,0,0"
RowHeight="60"
HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
BackgroundColor="Olive"
Grid.Row="1">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell IsEnabled="false">
<StackLayout BackgroundColor="#f4eac3"
Padding="0,5,0,5"
HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<StackLayout BackgroundColor="Transparent"
HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand"
Spacing="0"
Margin="20,0,20,0">
<Label Text="{Binding FullName}" TextColor="Maroon" VerticalOptions="CenterAndExpand" />
<Label Text="{Binding Profession}" TextColor="Maroon" VerticalOptions="CenterAndExpand" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer (typeof(ListView), typeof(CustomListViewRenderer))]
namespace yourNamespace
{
public class CustomListViewRenderer : ListViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
var listView = Control as UITableView;
listView.SeparatorInset = UIEdgeInsets.Zero;
}
}
}
}
That is due to the implementation of the ListView on the iOS side. It renders as a UITableView which (in the case of the ListView) always takes the entire height and shows empty items. To change this type of behavior you could set the ListView height dynamically in the code-behind for your page. Another option is taking a look at Xamarin's Evolve sample app which has a few pages where it uses a CardView combined with a ListView to make it appear as it does on Android.
In xamarin Android we have "Visibility.Gone;" to hide the button. In Xamarin Forms we have IsVisible="{Binding State}", but this only will make view invisible, space remain there.
Please let me know solution.
Regards
In your view model you need to have something similar to the following:
public bool State{
get {
return _state;
}
set {
_state= value;
RaisePropertyChanged ("State");
}
}
According to the Xamarin documentation found here the element should be removed from the visual tree and not take up any space.
Edit:
I'm not sure how you're setting the Column="5" on your grid. There is no attribute for Grid that contains column; however, I am able to produce the effect you looking for with the following code.
<Grid BackgroundColor="Gray">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Grid.Padding>
<OnPlatform x:TypeArguments="Thickness" iOS="0,-3,-20,-3" Android="0, -5, 0, -5" WinPhone="20, 20, 20, 20" />
</Grid.Padding>
<BoxView Color="Blue" Grid.Column="0"></BoxView>
<BoxView Color="Green" Grid.Column="1" IsVisible="{Binding State}"></BoxView>
<BoxView Color="Blue" Grid.Column="2"></BoxView>
<BoxView Color="Green" Grid.Column="3"></BoxView>
</Grid>
Details:
You are correct in that setting the label visibility to false in a grid will maintain the space allocated to the control in the grid. What you can do is set the grid <ColumnDefinition Width="Auto" /> or <RowDefinition Height="Auto" /> and put your label into that column or row. This will automatically remove the space allocated for the control when the visibility is set to false. Below is a screenshot of the effect you are getting (left) and the effect after setting the Definition to Auto (right).
I'm trying to create a scrollable area to display controls using the XAML code below. My problem is that I only see one item displayed when the items are rendered. I'm using an ObservableCollection for the data.
I've attached to the CollectionChanged event on the collection and definitely see multiple items being added but the view always displays only one item.
If I manually place HubTiles inside the WrapPanel (not databound) the tiles show up correctly. Also I tried replacing the hub tile with a button control and I do see multiple buttons, so I'm wondering if perhaps there is some issue with the HubTile control.
Here's my XAML:
<Grid x:Name="dataGrid" Grid.Row="1">
<ScrollViewer x:Name="myPanel" HorizontalAlignment="Stretch" Width="Auto" Margin="0" >
<toolkit:WrapPanel MaxWidth="{Binding ActualWidth, ElementName=myPanel, Mode=OneWay}" Margin="0" HorizontalAlignment="Center" ItemHeight="230" ItemWidth="230">
<ItemsControl x:Name="images">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<toolkit:HubTile
Style="{Binding Source={StaticResource media}}"
Message="{Binding Data.Caption}"
Source="{Binding Data.Source}"
/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</toolkit:WrapPanel>
</ScrollViewer>
</Grid>
Difficult to say without more information,
but the first thing I noticed is that you have a WrapPanel in a ScrollViewer,
and that WrapPanel contains an ItemsControl, with a WrapPanel as ItemsPanel.
The "inner" WrapPanel doesn't have an ItemWidth or ItemHeight. Is there any reason you have two WrapPanel's?
I have a popup within a user control. The popup uses a TextBox to show a textual preview of data produced by the control.
How do I make the popup size itself to the user control it's inside of? With code as shown below, I find that the text box is sized according to its content, and the popup is sized according to the textbox.
It works fine if I use fixed sizes in my row and column definitions, but I would like to popup to resize itself to match the user control (which in turn matches the browser).
<UserControl
<!-- usual stuff here -->
>
<Grid>
<!-- layout for the user control here -->
<!-- and after that my popup: -->
<Popup Name="MyPopup">
<Border BorderBrush="Black" BorderThickness="2" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="22"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Text="Preview:" Margin="5" ></TextBlock>
<TextBox
Grid.Row="1"
Name="MyTextBox"
IsReadOnly="True"
HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Visible"
TextWrapping="Wrap"
Margin="5"
>
</TextBox>
</Grid>
</Border>
</Popup>
</Grid></UserControl>
The C# code to do this would be something like:
textBox1.Width = UserControl.Width;
textBox1.Height = UserControl.Height;
textBox1.Margin = UserControl.Margin;
The key here is resetting the margin. I know this works in WPF to, say, fill a Window with a TextBox. Give it a try, see if it works.