I am using T4 template to generate datatemplate. here is the function which I am using.
public static bool AppendDataTemplate(string filePath, string dataTemplateToBeAppended)
{
try
{
XmlNode newDataTemplateNode = CreateNodeFromXmlString(dataTemplateToBeAppended);
if (newDataTemplateNode != null)
{
if (newDataTemplateNode.Attributes != null)
{
string itemTemplateKey = newDataTemplateNode.Attributes["x:Key"].Value;
XmlElement resourceDictionaryRoot;
XmlDocument existingXmlDocument = GetRootDocumentFromFile(filePath, out resourceDictionaryRoot);
if (resourceDictionaryRoot != null)
{
if (
resourceDictionaryRoot.ChildNodes.Cast<XmlNode>()
.Any(
node =>
node.Attributes != null && node.Attributes["x:Key"].Value == itemTemplateKey))
{
return true;
}
if (resourceDictionaryRoot.OwnerDocument != null)
{
XmlNode importNode = resourceDictionaryRoot.OwnerDocument.ImportNode(
newDataTemplateNode,
true);
resourceDictionaryRoot.AppendChild(importNode);
}
}
else
{
throw new ApplicationException(
"There is some issue while getting xml from the specified file");
}
existingXmlDocument.Save(filePath);
}
}
else
{
throw new ApplicationException("There is some issue while converting specified string to XML");
}
}
catch (Exception ex)
{
throw;
}
return true;
}
private static XmlNode CreateNodeFromXmlString(string xml)
{
var newDataTemplateDocument = new XmlDocument();
newDataTemplateDocument.XmlResolver = null;
newDataTemplateDocument.LoadXml(xml);
return newDataTemplateDocument.DocumentElement;
}
This is working fine but only issue is, I had to add xml namespace along with datatemplate else it throws error, is there anyway We can stop XML validation? see below template, if I pass without xmlns it throws validation error.. any suggestions?
<DataTemplate x:Key="PersonItemTemplate" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid HorizontalAlignment="Left" Width="250" Height="250">
<Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
<Image Source="{Binding ImageUrl}" Stretch="UniformToFill" />
</Border>
<StackPanel VerticalAlignment="Bottom" Background="{StaticResource ListViewItemOverlayBackgroundThemeBrush}">
<TextBlock Text="{Binding PersonName}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="40" Margin="15,0,15,0" />
<TextBlock Text="{Binding PersonId}" Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextStyle}" Margin="15,0,15,10" />
<TextBlock Text="{Binding PersonAddress}" Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextStyle}" Margin="15,0,15,10" />
<TextBlock Text="{Binding BirthDate}" Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextStyle}" Margin="15,0,15,10" />
</StackPanel>
</Grid>
</DataTemplate>
Related
I have tried adding the data to Listview using the public class 'Videotag' and a list 'initialList'. I'm trying to compare the listview selected item value to tags data from the RealtimeFirebase. The data from the firebase calls fine, but selected item value from listview returns null. Anyone know what i'm doing wrong?
public partial class videosection : ContentPage
{
List<videos> allVideos = new List<videos>();
List<Videotag> item = new List<Videotag>();
//List<string> initialList = new List<string>();
public videosection()
{
InitializeComponent();
//DependencyService.Get<IRotate>().ForcePortrait();
//initialList.Add("Shoulders");
//initialList.Add("Core");
//initialList.Add("Arms");
//initialList.Add("Hands");
//initialList.Add("Legs");
//initialList.Add("Balance");
//VideoLV.ItemsSource = initialList;
item.Add(new Videotag() { tags = "Shoulders" });
item.Add(new Videotag() { tags = "Core" });
item.Add(new Videotag() { tags = "Arms" });
item.Add(new Videotag() { tags = "Hands" });
item.Add(new Videotag() { tags = "Legs" });
item.Add(new Videotag() { tags = "Balance" });
VideoLV.ItemsSource = item;
//VideoLV.selectedi = item[0];
getvideo();
}
public class Videotag
{
public string tags { get; set; }
}
async private void getvideo()
{
allVideos = await DbFirebase.Getvideos();
//Adds videos to ItemsSource depending on the currently selected tag
//videosListView.ItemsSource = allVideos.Where(v => v.tag.Trim().ToLower() == (VideoLV.SelectedItem).ToString().Trim().ToLower()).ToList();
}
//private void SfChipGroup_SelectionChanged(object sender, Syncfusion.Buttons.XForms.SfChip.SelectionChangedEventArgs e)
//{
// videosListView.ItemsSource = allVideos.Where(v => v.tag.Trim().ToLower() == ((SfChip)chips.SelectedItem).Text.Trim().ToLower()).ToList();
//}
private async void Watch_Button_Clicked(object sender, EventArgs e)
{
string videoId = (string)((ImageButton)sender).BindingContext;
var video = allVideos.FirstOrDefault(v => v.id == videoId);
await Navigation.PushModalAsync(new SingleVideo(video), false);
}
private void VideoLV_ItemTapped(object sender, Syncfusion.ListView.XForms.ItemTappedEventArgs e)
{
//var indexes = e.ToString();
//String selectedFromList = VideoLV.getItemAtPosition(position);
//int myindex = VideoLV.Index(tags);
//vaVideoLV.selectedItem
//var selected = (videotag)e.SelectedItem;
videosListView.ItemsSource = allVideos.Where(v => v.tag.Trim().ToLower() == ((SfListView)VideoLV.SelectedItem).ToString().Trim().ToLower()).ToList();
}
<syncfusion:SfListView x:Name="VideoLV"
Padding="0"
AutoFitMode="Height"
Margin="10,0,10,0"
ItemTapped="VideoLV_ItemTapped"
BackgroundColor="Transparent"
SelectionMode="Single"
VerticalOptions="StartAndExpand"
IsScrollBarVisible="False"
SelectionBackgroundColor="Transparent"
Orientation="Horizontal"
HeightRequest="55">
<syncfusion:SfListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame CornerRadius="10" Margin="5,0,5,0" BackgroundColor="LightBlue" HasShadow="False" >
<Grid HorizontalOptions="StartAndExpand" Margin="0" Padding="0" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Text="{Binding tags}" Margin="0,-5,0,0" Grid.Row="0" VerticalOptions="StartAndExpand" TextColor="Black" FontSize="Small" />
</Grid>
</Frame>
</ViewCell>
</DataTemplate>
</syncfusion:SfListView.ItemTemplate>
<syncfusion:SfListView.SelectedItemTemplate>
<DataTemplate>
<ViewCell>
<Frame CornerRadius="10" Margin="5,0,5,0" BackgroundColor="LightBlue" HasShadow="False" BorderColor="Red">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Text="{Binding tags}" Margin="0,-5,0,0" VerticalOptions="CenterAndExpand" Grid.Row="0" TextColor="Red" FontSize="Small" />
</Grid>
</Frame>
</ViewCell>
</DataTemplate>
</syncfusion:SfListView.SelectedItemTemplate>
</syncfusion:SfListView>
you are trying to cast SelectedItem to SfListView, which is wrong
(SfListView)VideoLV.SelectedItem
the SelectedItem should be a Videotag
(Videotag)VideoLV.SelectedItem
I have a Label within my CollectionView that I need to populate with a value outside the ItemsSource List that populates the view.
The following code is an example of what I am trying to accomplish but it seems that the CollectionView is limiting the binding context to just the Items list. I have tried naming the label and setting it in my c# code but I cant seem to access the label in c#. I suppose I could build the whole page in c# rather than using the .xaml but unlike this example my actual code uses multiple templates and a template selector. If I could figure this out without rewriting hours of code I would prefer it.
ItemsPage.xaml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="TabTest.Views.ItemsPage"
Title="{Binding Title}"
x:Name="BrowseItemsPage">
<ContentPage.ToolbarItems>
<ToolbarItem Text="Add" Clicked="AddItem_Clicked" />
</ContentPage.ToolbarItems>
<StackLayout Padding="10">
<Label Text="{Binding TestVal}" FontSize="16" HeightRequest="20" />
<!-- ^^^^ This label displays just as expected -->
<RefreshView IsRefreshing="{Binding IsBusy, Mode=TwoWay}" Command="{Binding LoadItemsCommand}">
<CollectionView x:Name="ItemsCollectionView"
ItemsSource="{Binding Items}">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Padding="10">
<Label x:Name="TestV" Text="{Binding Path=BindingContext.TestVal}" />
<!-- ^^^^ I want this Label to display the TestVal string in the ViewModel -->
<Label Text="{Binding Text}"
d:Text="{Binding .}"
LineBreakMode="NoWrap"
Style="{DynamicResource ListItemTextStyle}"
FontSize="16" />
<Label Text="{Binding Description}"
d:Text="Item descripton"
LineBreakMode="NoWrap"
Style="{DynamicResource ListItemDetailTextStyle}"
FontSize="13" />
<StackLayout.GestureRecognizers>
<TapGestureRecognizer NumberOfTapsRequired="1" Tapped="OnItemSelected"></TapGestureRecognizer>
</StackLayout.GestureRecognizers>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</RefreshView>
</StackLayout>
</ContentPage>
ItemsViewModel.cs
namespace TabTest.ViewModels
{
public class ItemsViewModel : BaseViewModel
{
public ObservableCollection<Item> Items { get; set; }
public Command LoadItemsCommand { get; set; }
private string testVal;
public string TestVal // I want the value of this variable in that Label
{
get
{
return testVal;
}
set
{
testVal = value;
}
}
public ItemsViewModel()
{
Title = "Browse";
TestVal = "Value123";
Items = new ObservableCollection<Item>();
LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommand());
MessagingCenter.Subscribe<NewItemPage, Item>(this, "AddItem", async (obj, item) =>
{
var newItem = item as Item;
Items.Add(newItem);
await DataStore.AddItemAsync(newItem);
});
}
async Task ExecuteLoadItemsCommand()
{
IsBusy = true;
try
{
Items.Clear();
var items = await DataStore.GetItemsAsync(true);
foreach (var item in items)
{
Items.Add(item);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
finally
{
IsBusy = false;
}
}
}
}
I ended up using a dynamic resource in Xaml and used code behind to modify the resource when it needed to change.
Xaml:
<Label x:Name="TestV" Text="{DynamicResource TestValue}" />
Code Behind:
Application.Current.Resources["TestValue"] = NewValue;
App.xaml:
<x:String x:Key="TestValue">Value123</x:String>
I have mvc web api that post images. im trying to retrieve an image to my xamarin project using ImageSource.FromUri
Im totaly able to view this image in the web site. but not on my xamarin project.
what im i doing wrong i wonder. here is my code
API that post the image
[HttpGet]
[AllowAnonymous]
public ActionResult GetImage(string imagePath)
{
var path = Path.Combine(Actions.ImageRootPath, imagePath);
if (!System.IO.File.Exists(path))
return new EmptyResult();
var stream= System.IO.File.OpenRead(path);
return File(stream, "image/png");
}
xamarin xaml
<Frame Style="{StaticResource FrameContainer}" WidthRequest="200" HeightRequest="150" CornerRadius="10" BorderColor="Transparent">
<StackLayout Orientation="Vertical">
<Image Source="{Binding Logo, Converter={StaticResource ImageSource}}" WidthRequest="200" />
<StackLayout HorizontalOptions="CenterAndExpand" Style="{StaticResource Form}" Padding="10,0,0,0" Orientation="Vertical">
<Label Text="{Binding Name}" HorizontalOptions="Center" Style="{StaticResource Header}" />
<Label Text="{Binding TotalVideos}" IsVisible="{Binding TotalVideos, Converter={StaticResource StringNullOrEmpty}}" HorizontalOptions="Center" Style="{StaticResource UnderText}" />
</StackLayout>
</StackLayout>
</Frame>
ImageSource the converter
if (value is string && value != null && value.ToString().Length >= 4 && !value.ToString().Contains("http"))
{
byte[] Base64Stream = System.Convert.FromBase64String(value.ToString());
var img = ImageSource.FromStream(() => new MemoryStream(Base64Stream));
return img;
}
else if (value is string && !string.IsNullOrEmpty(value?.ToString() ?? "") && value.ToString().Contains("http"))
{
var uri = new Uri(value.ToString());
return ImageSource.FromUri(uri);
//var data = Helper.HttpHelper.GetImage(value.ToString());
//return GetImage(key, data.ToArray());
}
else if (value is byte[])
{
return ImageSource.FromStream(() => new MemoryStream(value as byte[]));
}
return ImageSource.FromFile("NoImage.png");
What i tried and worked but i dont like
This code below work but i have to download the image first using webclient
var data = Helper.HttpHelper.GetImage(value.ToString());
return ImageSource.FromStream(() => new MemoryStream(data));
Here is the image url
http://youtubemanager.ddns.net/Youtube.Manager.API/Images/GetImage?imagePath=alen.toma%5Cc2e8bcaa-e258-453b-84c4-868d23b03848.png
I'm new in Wpf and i face issue to get selected item in listbox
I created a simple xaml with a listbox and a textbox.
I use binding to populate my listbox including trigger (checked or not) that i want ot use later.
Xaml code:
<ListBox x:Name="LstB_Checklist" HorizontalAlignment="Left" Height="190" Margin="39,45,0,0" VerticalAlignment="Top" Width="275" Background="#FF363636" BorderBrush="{x:Null}" FontSize="18" Foreground="White" BorderThickness="2" SelectionChanged="LstB_Checklist_SelectionChanged" SelectedItem="{Binding SelectedProperty,Mode=TwoWay}" >
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True" >
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Background" Value="#FFFFDC00" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="LightGray"/>
</Style.Resources>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image>
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding Checked}" Value="false">
</DataTrigger>
<DataTrigger Binding="{Binding Checked}" Value="true">
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<TextBlock Text="{Binding Path=Title, Mode=TwoWay}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBox x:Name="txtb_Selection" HorizontalAlignment="Left" Height="23" Margin="60,264,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
in the code behind
public MainWindow()
{
InitializeComponent();
List<LstB_Item> items = new List<LstB_Item>();
items.Add(new LstB_Item() { Title = "Items 1", Checked = false });
items.Add(new LstB_Item() { Title = "Items 2", Checked = false });
items.Add(new LstB_Item() { Title = "Items 3", Checked = false });
LstB_Checklist.ItemsSource = items;
}
public class LstB_Item : INotifyPropertyChanged
{
public string Title { get; set; }
private bool _checked;
public bool Checked
{
get { return _checked; }
set { _checked = value; NotifyPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private void LstB_Checklist_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
txtb_Selection.Text = LstB_Checklist.SelectedItem.ToString();
}
The lisbox is populated correctly. My question is: What is the right code to get the value selected item.
Many thanks for the support
I'm afraid the question was not so clear or the answer evident, but i post an answer, it could help:
Possible answer:
var selected = LstB_Checklist.SelectedItem as LstB_Item;
txtb_Selection.Text = selected.Title;
I'm trying to create a login status control in silverlight where I will use multiple ControlTemplates to define conditional content.
So far I have created a LoginStatusControl
public class LoginStatusControl : ContentControl
{
// these are actually Depedency Properties
public ControlTemplate LoggedInTemplate { get; set; }
public ControlTemplate AnonymousTemplate { get; set; }
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var user = this.DataContext as User;
if (user == null && this.AnonymousTemplate != null)
{
this.Template = this.AnonymousTemplate;
}
else if (this.LoggedInTemplate != null)
{
this.Template = this.LoggedInTemplate;
}
}
}
Then I've defined the templates in a Style.
<Style x:Key="UserStatusStyle" TargetType="local:LoginStatusControl">
<Setter Property="LoggedInTemplate">
<Setter.Value>
<ControlTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="User " />
<TextBlock Text="{Binding FirstName}" />
<TextBlock Text=" " />
<TextBlock Text="{Binding LastName}" />
<TextBlock Text=" is logged in" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="AnonymousTemplate">
<Setter.Value>
<ControlTemplate>
<TextBlock Text="Please create your profile" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I'm having difficulty getting the conditional templates connected to override the ControlTemplate.
While searching I found this question and tried to use template binding but I couldn't get that to work.
Is there anyway to get this conditional templates to display if the user is logged in or not? Is there another way of solving this problem that I'm missing? I'm hoping to come up with a solution that can update the template dynamically when the DataContext of the control changes.
Well, I ended up going with a ContentContent's Content property and providing conditional DataTemplates.
Here is the Control:
public class LoginStatusControl : ContentControl
{
public DataTemplate LoggedInTemplate
{
get { return (DataTemplate)GetValue(LoggedInTemplateProperty); }
set { SetValue(LoggedInTemplateProperty, value); }
}
// Using a DependencyProperty as the backing store for LoggedInTemplate. This enables animation, styling, binding, etc...
public static readonly DependencyProperty LoggedInTemplateProperty =
DependencyProperty.Register("LoggedInTemplate", typeof(DataTemplate), typeof(LoginStatusControl), new PropertyMetadata(null));
public DataTemplate AnonymousTemplate
{
get { return (DataTemplate)GetValue(AnonymousTemplateProperty); }
set { SetValue(AnonymousTemplateProperty, value); }
}
// Using a DependencyProperty as the backing store for AnonymousTemplate. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AnonymousTemplateProperty =
DependencyProperty.Register("AnonymousTemplate", typeof(DataTemplate), typeof(LoginStatusControl), new PropertyMetadata(null));
public LoginStatusControl()
{
DefaultStyleKey = typeof(LoginStatusControl);
}
public override void OnApplyTemplate()
{
UpdateTemplate();
base.OnApplyTemplate();
}
private void UpdateTemplate()
{
var content = (ContentControl)base.GetTemplateChild("LoginControl");
if (content == null)
return;
var user= this.DataContext as User;
if (user == null && this.AnonymousTemplate != null)
{
content.Content = this.DataContext;
content.ContentTemplate = this.AnonymousTemplate;
}
else if (this.LoggedInTemplate != null)
{
content.Content = this.DataContext;
content.ContentTemplate = this.LoggedInTemplate;
}
}
}
And here is the Default Style.
<Style x:Key="LoginStatusStyle" TargetType="controls:LoginStatusControl">
<Setter Property="LoggedInTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="User: "/>
<TextBlock Text="{Binding FirstName}" FontWeight="Bold" />
<TextBlock Text=" " />
<TextBlock Text="{Binding LastName}" FontWeight="Bold" />
<TextBlock Text=" is logged in" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="AnonymousTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="Please create your profile" />
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ContentControl x:Name="LoginControl" Margin="10,0" VerticalAlignment="Center" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>