I use a SharpNado CollectionView in .NET MAUI with a DataTemplate as can be seen below.
There is also a Button which has its Button_Clicked-Event in the Code-Behind file. From there, I wanted to evaluate each MinEntry and MaxEntry that is displayed in CollectionView. There should be an evaluation like MinEntry-Value should always greater or equal to MaxEntry-Value, also that there are values entered at all.
My current problem is, how I could access the list of all MinEntrys and MaxEntrys? Currently, I am not able to get these Controls at all. I tried several ways with FindByName etc., but I always got "null" as the FindByName-Result.
How could I access and evaluate these Controls?
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewModels="clr-namespace:MyApp.ViewModels"
xmlns:sho="http://sharpnado.com"
x:DataType="viewModels:MyViewViewModel"
x:Class="MyApp.Pages.Views.MyView">
<ContentView.Resources>
<ResourceDictionary>
<DataTemplate x:Key="VerticalItemTemplate" x:DataType="{x:Type models:MySelection}">
<sho:DraggableViewCell x:Name="DraggableViewCell">
<ContentView x:Name="DraggableContentView">
<SwipeView>
<Frame HeightRequest="60" Padding="15, 5, 15, 0">
<Grid RowDefinitions="Auto" ColumnDefinitions="120, Auto, Auto, Auto, Auto, 70, Auto">
<Label Grid.Column="0" Text="{Binding Name}" VerticalOptions="CenterAndExpand"/>
<Entry Grid.Column="1" Placeholder="0" Text="{Binding Min, Mode=TwoWay}" VerticalOptions="Center" HorizontalTextAlignment="Center" TextChanged="Entry_TextChanged" x:Name="MinEntry"/>
<Entry Grid.Column="3" Placeholder="100" Text="{Binding Max, Mode=TwoWay}" VerticalOptions="Center" HorizontalTextAlignment="Center" TextChanged="Entry_TextChanged" x:Name="MaxEntry"/>
<Label Grid.Column="5" Text="0" VerticalOptions="Center" HorizontalOptions="EndAndExpand"/>
</Grid>
</Frame>
...
</SwipeView>
</ContentView>
</sho:DraggableViewCell>
</DataTemplate>
</ResourceDictionary>
</ContentView>
<StackLayout>
<sho:CollectionView x:Name="CollectionView"
CollectionPadding="10,10,10,10"
CurrentIndex="{Binding CurrentIndex}"
EnableDragAndDrop="True"
DragAndDropDirection="VerticalOnly"
DragAndDropTrigger="LongTap"
ItemHeight="60"
ItemsSource="{Binding SelectedItems, Mode=OneWay}"
ItemTemplate="{StaticResource VerticalItemTemplate}"
CollectionLayout="Vertical" />
</StackLayout>
</ContentView>
My current problem is, how I could access the list of all MinEntrys and MaxEntrys? Currently, I am not able to get these Controls at all. I tried several ways with FindByName etc., but I always got "null" as the FindByName-Result.
We usually use Data binding and MVVM to achieve this.
We can add two fields (e.g. MinValue
and MaxValue
) to the Item model and implement interface INotifyPropertyChanged
.While changing the value of the two fields in the UI, the background value (MinValue
and MaxValue
) will also change.
I have created a demo based on the CollectionView
on maui.
You can refer to the following code:
1.create item model ItemModel.cs
public class ItemModel: INotifyPropertyChanged
{
public string Name { get; set; }
public string Description { get; set; }
//public int MinValue { get; set; }
private int minValue;
public int MinValue
{
get => minValue;
set
{
SetProperty(ref minValue, value);
}
}
//public int MaxValue { get; set; }
private int maxValue;
public int MaxValue
{
get => maxValue;
set
{
SetProperty(ref maxValue, value);
}
}
bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Object.Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
2.create a ViewModel MyViewModel.cs
public class MyViewModel
{
public ObservableCollection<ItemModel> Items { get; set; }
public ICommand GetResultCommand { get; set; }
public MyViewModel()
{
Items = new ObservableCollection<ItemModel>();
Items.Add(new ItemModel { Name = "test1", Description = "Description 1" });
Items.Add(new ItemModel { Name = "test2", Description = "Description 2" });
Items.Add(new ItemModel { Name = "test3", Description = "Description 3" });
GetResultCommand = new Command(GetResult);
}
private void GetResult()
{
foreach (var item in Items)
{
System.Diagnostics.Debug.WriteLine("--->The result is: " + item.Name+ "Min Value = " + item.MinValue +" <--> MaxValue = " + item.MaxValue);
}
}
}
3.Usage example:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiMvvmApp226.CollectionViewPage"
xmlns:MauiMvvmApp="clr-namespace:MauiMvvmApp226"
Title="CollectionViewPage">
<ContentPage.BindingContext>
<MauiMvvmApp:MyViewModel></MauiMvvmApp:MyViewModel>
</ContentPage.BindingContext>
<ContentPage.Resources>
<ResourceDictionary>
<DataTemplate x:Key="personTemplate">
<HorizontalStackLayout >
<StackLayout Orientation="Vertical">
<Label Text="{Binding Name}" FontSize="Title" />
<Label Text="{Binding Description}" FontSize="Subtitle"/>
</StackLayout>
<Label Text="Min:" Margin="10,0,10,0"></Label>
<Entry Text="{Binding MinValue}" WidthRequest="60"></Entry>
<Label Text="Max:" Margin="10,0,10,0"></Label>
<Entry Text="{Binding MaxValue}" WidthRequest="60"></Entry>
</HorizontalStackLayout>
</DataTemplate>
</ResourceDictionary>
</ContentPage.Resources>
<VerticalStackLayout>
<Button Text="Result" Command="{Binding GetResultCommand}" HorizontalOptions="FillAndExpand" Margin="10"/>
<CollectionView ItemsSource="{Binding Items}" ItemTemplate="{StaticResource personTemplate}" x:Name="mCollectionView" >
</CollectionView>
</VerticalStackLayout>
</ContentPage>