Initially, I did the navigation.popasync on second page back to main page and passed in the values inside the navigation.pushasync. However, now I want to go to a third page, and then do a update of time stamp lblEndDT in third page. I want to update lblEndDT on main page but btnDone in Third Page. How do I pass the value from main page to third page?
Main Page
public partial class MainPage : ContentPage
{
public string mainpagevalue;
int offlinecount = 0;
int onlinecount = 0;
public MainPage()
{
InitializeComponent();
}
private void btnOffline_Clicked(object sender, EventArgs e)
{
offlinecount++;
//Navigation.PushAsync(new SecondPage(this, lblEndDT));
Navigation.PushAsync(new OfflinePage(this, lblEndDT, btnOnline));
if (offlinecount == 1)
{
string currentDT = DateTime.Now.ToString();
lblStartDT.Text = currentDT;
}
}
private void btnOnline_Clicked(object sender, EventArgs e)
{
onlinecount++;
Navigation.PushAsync(new OnlinePage());
if (onlinecount == 1)
{
string currentDT = DateTime.Now.ToString();
lblStartDT.Text = currentDT;
}
}
}
}
main page xaml
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="70"/>
<RowDefinition Height="30"/>
<RowDefinition Height="20"/>
<RowDefinition Height="70"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="10"/>
<RowDefinition Height="70"/>
<RowDefinition Height="30"/>
<RowDefinition Height="20"/>
<RowDefinition Height="70"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="10"/>
<RowDefinition Height="70"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="10"/>
<RowDefinition Height="70"/>
<RowDefinition Height="30"/>
<RowDefinition Height="20"/>
<RowDefinition Height="70"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="10"/>
<RowDefinition Height="70"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="10"/>
<RowDefinition Height="50"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="60" />
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="70"/>
</Grid.ColumnDefinitions>
<!--OFFLINE TOOL-->
<ImageButton x:Name="btnOffline" IsEnabled="True" Source="#drawable/offlinetool.png" Grid.Row="1" Grid.Column="1" BackgroundColor="Transparent" Clicked="btnOffline_Clicked"/>
<Label Text="Offline Tool" Grid.Row="2" Grid.Column="1" Margin="15,0,0,0"/>
<Label Text="Start Date Time:" Grid.Row="1" Grid.Column="3"/>
<Label Text="End Date Time:" Grid.Row="1" Grid.Column="3" Margin="7,40,0,0"/>
<Label x:Name="lblStartDT" Text="" Grid.Column="4" Grid.Row="1"/>
<Label x:Name="lblEndDT" Text="" Grid.Column="4" Grid.Row="1" Margin="0,40,0,0"/>
<!--ONLINE TOOL-->
<ImageButton x:Name="btnOnline" Source="#drawable/ot.png" Grid.Row="8" Grid.Column="1" BackgroundColor="Transparent" IsEnabled="False" Clicked="btnOnline_Clicked"/>
<Label Text="Online Tool" Grid.Row="9" Grid.Column="1" Margin="19,0,0,0"/>
<Label Text="Start Date Time:" Grid.Row="8" Grid.Column="3" />
<Label Text="End Date Time:" Grid.Row="8" Grid.Column="3" Margin="7,40,0,0"/>
<Label Text="Status:" Grid.Row="9" Grid.Column="3" Margin="58,0,0,0" />
<Label x:Name="lblOnlineStartDT" Text="" Grid.Column="4" Grid.Row="8"/>
<Label x:Name="lblOnlineEndDT" Text="" Grid.Column="4" Grid.Row="8" Margin="0,40,0,0"/>
<Label x:Name="txtOnlineStatus" Text="NOT STARTED" TextColor="Red" Grid.Column="4" Grid.Row="9"/>
</Grid>
Offline Page
public partial class OfflinePage : ContentPage
{
Label offlineEndDT;
MainPage mainpage;
ImageButton btnonline;
public OfflinePage()
{
InitializeComponent();
}
public OfflinePage(MainPage mpage, Label endDT, ImageButton onlineimage)
{
InitializeComponent();
mainpage = mpage;
offlineEndDT = endDT;
btnonline = onlineimage;
}
private void Button_Clicked(object sender, EventArgs e)
{
App.offlineDonecount++;
if (App.offlineDonecount == 1)
{
string edt = DateTime.Now.ToString();
offlineEndDT.Text = edt;
mainpage.mainpagevalue = offlineEndDT.Text;
}
btnonline.Source = "onlinetool";
btnonline.IsEnabled = true;
Navigation.PopAsync();
}
}
}
Online Page
public partial class OnlinePage : ContentPage
{
public OnlinePage()
{
InitializeComponent();
}
private void Button_Clicked(object sender, EventArgs e)
{
Navigation.PushAsync(new ThirdPage());
}
}
}
Third Page
public partial class ThirdPage : ContentPage
{
public ThirdPage()
{
InitializeComponent();
}
private void BtnDone_Clicked(object sender, EventArgs e)
{
}
}
}
Updated:
Create the TimeStamp model with Online, Offline Start and End time.
public class TimeStamp
{
public string OnlineStartTime { get; set; }
public string OnlineEndTime { get; set; }
public string OfflineStartTime { get; set; }
public string OfflineEndTime { get; set; }
}
MainPage:
Xaml:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="70" />
<RowDefinition Height="30" />
<RowDefinition Height="20" />
<RowDefinition Height="70" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="10" />
<RowDefinition Height="70" />
<RowDefinition Height="30" />
<RowDefinition Height="20" />
<RowDefinition Height="70" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="10" />
<RowDefinition Height="70" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="10" />
<RowDefinition Height="70" />
<RowDefinition Height="30" />
<RowDefinition Height="20" />
<RowDefinition Height="70" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="10" />
<RowDefinition Height="70" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="10" />
<RowDefinition Height="50" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="60" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="70" />
</Grid.ColumnDefinitions>
<!-- OFFLINE TOOL -->
<ImageButton
x:Name="btnOffline"
Grid.Row="1"
Grid.Column="1"
BackgroundColor="Transparent"
Clicked="btnOffline_Clicked"
IsEnabled="True"
Source="monkeyicon.png" />
<Label
Grid.Row="2"
Grid.Column="1"
Margin="15,0,0,0"
Text="Offline Tool" />
<Label
Grid.Row="1"
Grid.Column="3"
Text="Start Date Time:" />
<Label
Grid.Row="1"
Grid.Column="3"
Margin="0,40,0,0"
Text="End Date Time:" />
<Label
x:Name="lblStartDT"
Grid.Row="1"
Grid.RowSpan="2"
Grid.Column="4"
Grid.ColumnSpan="2"
Text="{Binding OfflineStartTime}" />
<Label
x:Name="lblEndDT"
Grid.Row="1"
Grid.RowSpan="2"
Grid.Column="4"
Grid.ColumnSpan="2"
Margin="0,40,0,0"
Text="{Binding OfflineEndTime}" />
<!-- ONLINE TOOL -->
<ImageButton
x:Name="btnOnline"
Grid.Row="8"
Grid.Column="1"
BackgroundColor="Transparent"
Clicked="btnOnline_Clicked"
IsEnabled="True"
Source="star_small.png" />
<Label
Grid.Row="9"
Grid.Column="1"
Margin="19,0,0,0"
Text="Online Tool" />
<Label
Grid.Row="8"
Grid.Column="3"
Text="Start Date Time:" />
<Label
Grid.Row="8"
Grid.Column="3"
Margin="7,40,0,0"
Text="End Date Time:" />
<Label
Grid.Row="9"
Grid.Column="3"
Margin="58,0,0,0"
Text="Status:" />
<Label
x:Name="lblOnlineStartDT"
Grid.Row="8"
Grid.RowSpan="2"
Grid.Column="4"
Grid.ColumnSpan="2"
Text="{Binding OnlineStartTime}" />
<Label
x:Name="lblOnlineEndDT"
Grid.Row="8"
Grid.RowSpan="2"
Grid.Column="4"
Grid.ColumnSpan="2"
Margin="0,40,0,0"
Text="{Binding OnlineEndTime}" />
<Label
x:Name="txtOnlineStatus"
Grid.Row="9"
Grid.Column="4"
Text="NOT STARTED"
TextColor="Red" />
</Grid>
Code:
public partial class MainPage : ContentPage
{
public string mainpagevalue;
int offlinecount = 0;
int onlinecount = 0;
public static TimeStamp timeStamp = new TimeStamp();
public MainPage()
{
InitializeComponent();
}
private async void btnOnline_Clicked(object sender, EventArgs e)
{
onlinecount++;
if (onlinecount == 1)
{
string currentDT = DateTime.Now.ToString();
lblOnlineStartDT.Text = currentDT;
timeStamp.OnlineStartTime = currentDT;
}
await Navigation.PushAsync(new OnlinePage());
}
private void btnOffline_Clicked(object sender, EventArgs e)
{
offlinecount++;
//Navigation.PushAsync(new SecondPage(this, lblEndDT));
Navigation.PushAsync(new OfflinePage(this, lblEndDT, btnOnline));
if (offlinecount == 1)
{
string currentDT = DateTime.Now.ToString();
lblStartDT.Text = currentDT;
timeStamp.OfflineStartTime = currentDT;
}
}
}
OfflinePage:
public partial class OfflinePage : ContentPage
{
Label offlineEndDT;
MainPage mainpage;
ImageButton btnonline;
public OfflinePage()
{
InitializeComponent();
}
public OfflinePage(MainPage mpage, Label endDT, ImageButton onlineimage)
{
InitializeComponent();
mainpage = mpage;
offlineEndDT = endDT;
btnonline = onlineimage;
}
private void Button_Clicked(object sender, EventArgs e)
{
App.offlineDonecount++;
if (App.offlineDonecount == 1)
{
string edt = DateTime.Now.ToString();
offlineEndDT.Text = edt;
mainpage.mainpagevalue = offlineEndDT.Text;
MainPage.timeStamp.OfflineEndTime = edt;
}
btnonline.IsEnabled = true;
Navigation.PopAsync();
}
}
OnlinePage:
private void Button_Clicked(object sender, EventArgs e)
{
Navigation.PushAsync(new ThirdPage());
}
ThirdPage:
private async void BtnDone_Clicked(object sender, EventArgs e)
{
MainPage.timeStamp.OnlineEndTime = DateTime.Now.ToString();
MainPage mainPage = new MainPage();
mainPage.BindingContext = MainPage.timeStamp;
await Navigation.PushAsync(mainPage);
}
Related
I'm working in a Xamarin Form Project . The form entered values are not showing in the Binding context . Binding Context Always shows the Initial value not the Latest Value .I have added my forms xaml part and View related View model class.Is there any Addition configurations to enable 2 way binding
Xaml Page
<StackLayout Grid.Row="0" Grid.Column="0">
<Grid x:Name="grid">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label x:Name="labelName" Grid.Row="0" Grid.Column="0" Margin="10" FontSize="6" VerticalOptions="CenterAndExpand" HorizontalTextAlignment="Start" Text="Name"/>
<Entry x:Name="textName" Grid.Row="0" Grid.Column="1" WidthRequest="100" FontSize="6" VerticalOptions="CenterAndExpand" HorizontalOptions="Start" HorizontalTextAlignment="Start" Text="{Binding Name,Mode=TwoWay}" />
<Label x:Name="labelAge" Grid.Row="1" Grid.Column="0" Margin="10" FontSize="6" Text="Age" VerticalOptions="CenterAndExpand" HorizontalTextAlignment="Start" />
<Entry x:Name="textAge" Grid.Row="1" Grid.Column="1" WidthRequest="100" FontSize="6" VerticalOptions="CenterAndExpand" HorizontalOptions="Start" HorizontalTextAlignment="Start" Text="{Binding Age,Mode=TwoWay}" />
<Label x:Name="labelAddress" Grid.Row="2" Grid.Column="0" Margin="10" FontSize="6" Text="Address" VerticalOptions="CenterAndExpand" HorizontalTextAlignment="Start" />
<Entry x:Name="textAddress" Grid.Row="2" Grid.Column="1" WidthRequest="100" FontSize="6" VerticalOptions="CenterAndExpand" HorizontalOptions="Start" HorizontalTextAlignment="Start" Text="{Binding Address,Mode=TwoWay}" />
<Label x:Name="labelNICNumber" Grid.Row="3" Grid.Column="0" Margin="10" FontSize="6" Text="NIC" VerticalOptions="CenterAndExpand" HorizontalTextAlignment="Start" />
<Entry x:Name="textNIC" Grid.Row="3" Grid.Column="1" WidthRequest="100" FontSize="6" VerticalOptions="CenterAndExpand" HorizontalOptions="Start" HorizontalTextAlignment="Start" Text="{Binding NIC,Mode=TwoWay}" />
<Button Grid.Row="4" Grid.Column="1" HeightRequest = "30" VerticalOptions="CenterAndExpand" HorizontalOptions="Start" FontSize="6" Text="Save" Clicked="UserSaveClick" />
</Grid>
</StackLayout>
ViewModel
public event PropertyChangedEventHandler PropertyChanged;
private string userName ;
private string name;
private int age ;
private bool isBusy;
private string address;
private int nic;
void OnPropertyChanged([CallerMemberName] string name = "")
{
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(name));
}
public int NIC
{
get { return nic; }
set
{
nic = value;
OnPropertyChanged();
}
}
public string Name
{
get { return name; }
set
{
name = value;
IsBusy = Name == "aa" ? true : false;
OnPropertyChanged();
OnPropertyChanged(nameof(DisplayMessage));
}
}
public int Age
{
get { return age; }
set
{
age = value;
OnPropertyChanged();
}
}
public string Address
{
get { return address; }
set
{
address = value;
OnPropertyChanged();
}
}
public string DisplayMessage
{
get
{
return "Hi " + name;
}
}
public bool IsBusy
{
get { return isBusy; }
set { isBusy = value; }
}
}
Also check that you properly setter method is not private. I lost some hours to find out this simple copy paste error.
I was getting this error in the debug output Binding: 'xxx' property not found on 'yyyy', target property: 'Xamarin.Forms.Entry.Text'.
by the way this error message is not super clear.
Can you check:
1.When entering text in the entry control,check it is hitting the break point in the view model for each property.
2.Check INotifyPropertyChanged is implemented.
3.Check by setting the hard code for the Text property of Entry control.
How can I remove the row Comment is on if its null or empty string?
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30*" />
<ColumnDefinition Width="50*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding EntryDate}" Grid.Column="0" Grid.Row="0"></Label>
<Label Text="{Binding Sleep}" Grid.Column="1" Grid.Row="0"></Label>
<Label Text="{Binding Comment}" Grid.Column="0" Grid.ColumnSpan="4"
Grid.Row="1"></Label>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
This is the appropriate case to use a ValueConverter.
All you need to do is create a converter like this:
namespace App.Converters
{
public class TextToBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value != null)
if (!(value is string)) return true;
return string.IsNullOrWhiteSpace(value as string) ? false : true;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
And use it on the IsVisible property of Label:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:converters="clr-namespace:App.Converters"
x:Class="App.Views.SamplePage">
<ContentPage.Resources>
<ResourceDictionary>
<converters:TextToBoolConverter x:Key="TextToBoolConverter" />
</ResourceDictionary>
</ContentPage.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30*" />
<ColumnDefinition Width="50*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding EntryDate}" Grid.Column="0" Grid.Row="0"></Label>
<Label Text="{Binding Sleep}" Grid.Column="1" Grid.Row="0"></Label>
<Label Text="{Binding Comment}" Grid.Column="0" Grid.ColumnSpan="4"
Grid.Row="1"
IsVisible={Binding Comment, Converter={StaticResource TextToBoolConverter}}/>
</Grid>
</ContentPage>
Thus you can reuse it wherever you need.
Your model:
public class MyModel
{
//...other properties ...
public string Comment { get; set; }
public bool HasComment => !string.IsNullOrEmpty(Comment);
}
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30*" />
<ColumnDefinition Width="50*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding EntryDate}" Grid.Column="0" Grid.Row="0"></Label>
<Label Text="{Binding Sleep}" Grid.Column="1" Grid.Row="0"></Label>
<Label Text="{Binding Comment}" Grid.Column="0" Grid.ColumnSpan="4"
Grid.Row="1" IsVisible = {Binding HasComment}></Label>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
I want to insert a syncfusion linearlayout listview, but for some reason it's not displaying any items/data, and I'm not getting any errors at the same time, I tried changing binding syntax and a couple things, but I cannot seem to get it right.
This is my xaml:
<syncfusion:SfListView x:Name="listView"
ItemTemplate="{Binding Source={local2:BandInfoRepository}, Path=BandInfo, Mode=TwoWay}"
ItemSize="100"
AbsoluteLayout.LayoutBounds="1,1,1,1"
AbsoluteLayout.LayoutFlags="All" >
<syncfusion:SfListView.ItemTemplate>
<DataTemplate>
<Grid RowSpacing="0" Padding="0,12,8,0" ColumnSpacing="0" Margin="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="1" />
</Grid.RowDefinitions>
<Grid RowSpacing="0" Padding="8,0,8,10">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image Source="{Binding Path=BandImage}"
Grid.Column="0"
Grid.Row="0"
HeightRequest="80"
WidthRequest="70"
HorizontalOptions="Start"
VerticalOptions="Start"
/>
<StackLayout Orientation="Vertical"
Padding="5,-5,0,0"
VerticalOptions="Start"
Grid.Row="0"
Grid.Column="1">
<Label Text="{Binding Path=BandName}"
FontAttributes="Bold"
FontSize="16"
BackgroundColor="Green"
TextColor="#000000" />
<Label Text="{Binding Path=BandDescription}"
Opacity="0.54"
BackgroundColor="Olive"
TextColor="#000000"
FontSize="13" />
</StackLayout>
</Grid>
<BoxView Grid.Row="1"
HeightRequest="1"
Opacity="0.75"
BackgroundColor="#CECECE" />
</Grid>
</DataTemplate>
</syncfusion:SfListView.ItemTemplate>
</syncfusion:SfListView>
And this is the class where I'm getting the data from:
public class BandInfo : INotifyPropertyChanged
{
private string bandName;
private string bandDesc;
private ImageSource _bandImage;
public string BandName
{
get { return bandName; }
set
{
bandName = value;
OnPropertyChanged("BandName");
}
}
public string BandDescription
{
get { return bandDesc; }
set
{
bandDesc = value;
OnPropertyChanged("BandDescription");
}
}
public ImageSource BandImage
{
get { return _bandImage; }
set
{
_bandImage = value;
OnPropertyChanged("BandImage");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string name)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
And just in case, this is how I'm filling the collection (BandInfoRepository.cs):
public class BandInfoRepository
{
private ObservableCollection<BandInfo> bandInfo;
public ObservableCollection<BandInfo> BandInfo
{
get { return bandInfo; }
set { this.bandInfo = value; }
}
public BandInfoRepository()
{
GenerateBookInfo();
}
internal void GenerateBookInfo()
{
string[] BandNames = new string[] {
"Nirvana",
"Metallica",
"Frank Sinatra"
};
string[] BandDescriptions = new string[] {
"Description",
"Description",
"Description"
};
bandInfo = new ObservableCollection<BandInfo>();
for (int i = 0; i < BandNames.Count(); i++)
{
var band = new BandInfo()
{
BandName = BandNames[i],
BandDescription = BandDescriptions[i],
BandImage = ImageSource.FromResource("Lim.Images.Image" + i + ".png")
};
bandInfo.Add(band);
}
}
}
I hope you guys can help me out as I've been stuck with this for a while now. Thanks in advance.
Looks like you unintentionally bind ItemTemplate twice and not bind any
ItemsSource even once.
We have looked into your code snippet and we have found that you have binded the underlying collection to ItemTemplate property instead of ItemsSource property. Further to bind the underlying collection you have to set your ViewModel(i.e. BandInfoRepository) as BindingContext for ContentPage. Please refer the below code snippets to know how to set BindingContext for your page and also to bind the underlying collection into the ItemsSource property.
Code Example:[XAML]
<ContentPage>
<ContentPage.BindingContext>
<local:BandInfoRepository/>
</ContentPage.BindingContext>
<ContentPage.Content>
<listView:SfListView x:Name="listView" ItemSize="70" ItemsSource="{Binding BandInfo}" >
<listView:SfListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid x:Name="grid" RowSpacing="1">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="1" />
</Grid.RowDefinitions>
<Grid RowSpacing="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding BandImage}"
VerticalOptions="Center"
HorizontalOptions="Center"
HeightRequest="50" Aspect="AspectFit"/>
<Grid Grid.Column="1"
RowSpacing="1"
Padding="10,0,0,0"
VerticalOptions="Center">
<Label Text="{Binding ContactName}"/>
</Grid>
</Grid>
<StackLayout Grid.Row="1" BackgroundColor="Gray" HeightRequest="1"/>
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</listView:SfListView.ItemTemplate>
</listView:SfListView>
</ContentPage.Content>
</ContentPage>
For your assistance, we have attached the working sample link below.
Sample link: http://www.syncfusion.com/downloads/support/directtrac/186932/ze/ListViewSample905947849
I'm looking for something like a dynamic margin or flexible space in XAML but couldn't find something.
This XAML:
<HubSection VerticalContentAlignment="Stretch">
<DataTemplate>
<Grid>
<TextBlock Text="Products>" Foreground="#FF464646" FontSize="36" Margin="0,-50,0,0"></TextBlock>
<StackPanel VerticalAlignment="Center">
<Button Background="#FF00AEFF" Width="260" Height="60" Content="Button1"></Button>
<Button Background="#FFFF8000" Width="260" Height="60" Content="Button2"></Button>
<Button Background="#FFDE0101" Width="260" Height="60" Content="Button3"></Button>
<Button Background="#FF6300DA" Width="260" Height="60" Content="Button4"></Button>
<Button Background="#FF973E00" Width="260" Height="60" Content="Button5"></Button>
<Button Background="#FF00AA1F" Width="260" Height="60" Content="Button6"></Button>
</StackPanel>
</Grid>
</DataTemplate>
</HubSection>
Gives me:
But the buttons should have margins between them to fill the space according to the available screen height.
Something like this:
Is there something like a dynamic margin height?
Make it grid and it will work like a charm.
<HubSection VerticalContentAlignment="Stretch">
<DataTemplate>
<Grid VerticalAlignment="Stretch" Background="Yellow">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="Products>" Foreground="#FF464646" FontSize="36" Grid.Row="0"></TextBlock>
<Grid VerticalAlignment="Stretch" Background="Pink" Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Button Background="#FF00AA1F" Width="260" Height="60" Content="Button6" Grid.Row="6"></Button>
</Grid>
<Grid Grid.Row="1">
<Button Background="#FF00AEFF" Width="260" Height="60" Content="Button1" ></Button>
</Grid>
<Grid Grid.Row="2">
<Button Background="#FFFF8000" Width="260" Height="60" Content="Button2" Grid.Row="2"></Button>
</Grid>
<Grid Grid.Row="3">
<Button Background="#FFDE0101" Width="260" Height="60" Content="Button3" Grid.Row="3"></Button>
</Grid>
<Grid Grid.Row="4">
<Button Background="#FF6300DA" Width="260" Height="60" Content="Button4" Grid.Row="4"></Button>
</Grid>
<Grid Grid.Row="5">
<Button Background="#FF973E00" Width="260" Height="60" Content="Button5" Grid.Row="5"></Button>
</Grid>
</Grid>
</Grid>
</DataTemplate>
</HubSection>
This will solve your problem. I have added colors just that you know which grid is using which space.
If you do not want to hardcode the XAML and keep the XAML clean, be able to add items, I have created the SpaceChildrenBehavior
<Grid Background="AliceBlue" >
<i:Interaction.Behaviors>
<local:SpaceChildrenBehavior/>
</i:Interaction.Behaviors>
<Button Margin="0,10,0,0" Background="#FF00AEFF" Width="260" Height="60" Content="Button1"></Button>
<Button Background="#FFFF8000" Width="260" Height="60" Content="Button2"></Button>
<Button Background="#FFDE0101" Width="260" Height="60" Content="Button3"></Button>
<Button Background="#FF6300DA" Width="260" Height="60" Content="Button4"></Button>
<Button Background="#FF973E00" Width="260" Height="60" Content="Button5"></Button>
<Button Background="#FF00AA1F" Width="260" Height="60" Content="Button6"></Button>
</Grid>
This is the XAML (really clean)
and the behaviour
public class SpaceChildrenBehavior : DependencyObject, IBehavior
{
public DependencyObject AssociatedObject { get; private set; }
public Grid AssociatedGrid;
EventHandler<object> layoutupdated= null;
public void Attach(DependencyObject associatedObject)
{
AssociatedObject = associatedObject;
AssociatedGrid = associatedObject as Grid;
layoutupdated = async (s, e) =>
{
if (AssociatedGrid.ActualHeight > 0)
{
AssociatedGrid.LayoutUpdated -= layoutupdated;
await Task.Delay(100);
AssociatedGrid.RowDefinitions.Clear();
int i = -1;
foreach (var child in AssociatedGrid.Children)
{
AssociatedGrid.RowDefinitions.Add(new RowDefinition()
{ Height = new GridLength(1, GridUnitType.Star) });
Grid.SetRow(child as FrameworkElement, ++i);
}
AssociatedGrid.LayoutUpdated += layoutupdated;
}
};
AssociatedGrid.LayoutUpdated += layoutupdated;
}
public void Detach()
{
AssociatedGrid.LayoutUpdated -= layoutupdated;
}
}
Now is dynamic, you can add more items and it will adapt the grid rows
I have a xaml :
<phone:LongListSelector Name="llsSourceNews" ItemsSource="{Binding SourceNews}">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<Grid x:Name="gridNews">
<Grid.RowDefinitions>
<RowDefinition Height="80" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="250"/>
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<Image Grid.Row="0" Grid.Column="0" Source="{Binding icon}" Stretch="Fill" Height="35" Width="70"></Image>
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Name}" Foreground="White" TextWrapping="Wrap" FontSize="24" VerticalAlignment="Center"></TextBlock>
<Image Grid.Row="0" Grid.Column="2" Source="/Images/Add-New.png" x:Name="imgAdd" Tap="imgAdd_Tap"></Image>
</Grid>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
and tap event :
private void imgAdd_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
if(true)
{
this.Visibility = Visibility.Collapsed;
}
}
My problem is : when user tap image,all image is disable.I want to image is disable which is selected.
this in your case refers to the page. If you want to retrieve the image, you have to cast the sender parameter:
private void imgAdd_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
if(true)
{
var element = (FrameworkElement)sender;
element.Visibility = Visibility.Collapsed;
}
}