How to adapt Device.OnPlataform to switch(Device.RuntimePlatform)? - c#

I need to "update" the following code:
namespace Pizzahouse.Pages
{
public class IndexPage : ContentPage
{
public IndexPage()
{
Title = "Index";
var telephone = new Button()
{
Text = "Call",
WidthRequest = 50,
};
telephone.Clicked += (sender, e) => Device.OpenUri(new Uri("tel://123465789"));
Content = new ContentView()
{
Content = new StackLayout()
{
Children = {
new Image
{
Aspect = Aspect.AspectFit,
Source = Device.OnPlatform(
ImageSource.FromFile("PizzaIcon.png"),
ImageSource.FromFile("PizzaIcon.png"),
null)
}, telephone
}
}
};
}
}
}
I need to insert an image, but Xamarin.Forms says that the Device.OnPlataform() method is obsolete, and it says that I should use switch(Device.RuntimePlatform).
This exact code works, so what do you suggest? Thanks in advice.

Source = (Device.RuntimePlatform == Device.WinPhone) ? null : ImageSource.FromFile("PizzaIcon.png");

Related

My code-generated ListBox's items isn't showing any content

I have a code-generated window in WPF, (using dotnet core 3.0 preview 6), and when running my application gets the correct data, and the ListBox is populated with the correct number of rows, but none of them contains values
This is a test-project I'm doing to get familiar with code generated WPF as it's needed for an upcoming project we're doing at work; I would have preferred using XAML but my lead says that that will create issues with code-re-usability.
I at first made sure I used am object which is "clean", (my entities are setup for Linq2db, so I ensured that the attributes couldn't be the culprit), then I tested binding, (just got the "Error 40" -error code, but that isn't relevant to the main problem). I have also changed the type of boxes, but It does not help, (DataGrid did work but it's not what I'm looking for in a visual).
public class ChatWindow : IChatWindow
{
private ObservableCollection<MessageDto> _observableMessages;
private readonly IMessagesRepository _messagesRepository;
public ChatWindow(IMessagesRepository messagesRepository)
{
_messagesRepository = messagesRepository;
Task.Run(async () => { await Updater(); }).ConfigureAwait(false);
}
public async Task ShowAsync(User user)
{
var chatLog = new ListBox()
{
Name = "Chatview",
ItemsSource = _observableMessages,
ItemTemplate = new DataTemplate(typeof(MessageDto)),
DataContext = _observableMessages
};
//var myBinding = new Binding("_observableMessages");
//myBinding.Source = _observableMessages;
//chatLog.SetBinding(ListBox.ItemsSourceProperty, myBinding);
var input = new TextBox()
{
Name = "InputField",
Background = new SolidColorBrush(Color.FromRgb(35, 35, 35))
};
var stackPanel = new StackPanel()
{
Children =
{
chatLog,
input
}
};
var window = new Window()
{
Name = "ChatWindow",
Content = stackPanel,
};
window.Show();
}
private async Task Updater()
{
while (true)
{
var messages = await _messagesRepository.GetAllMessages(1);
_observableMessages = new ObservableCollection<MessageDto>(messages.Select(m => new MessageDto()
{
Timestamp = m.Timestamp,
From = m.From,
Message = m.Message
}));
await Task.Delay(TimeSpan.FromSeconds(10));
}
}
}
class MessageDto
{
public DateTime Timestamp { get; set; }
public long From { get; set; }
public string Message { get; set; }
}
Image of the resultant window, (some styling code was removed from the example code to reduce noise)
Based on Flithor's comment, i did this and it worked perfectly:
private DataTemplate GetDataTemplate()
{
var dataTemplate = new DataTemplate(typeof(MessageDto));
FrameworkElementFactory stackPanelFactory = new FrameworkElementFactory(typeof(StackPanel));
stackPanelFactory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
FrameworkElementFactory timestamp = new FrameworkElementFactory(typeof(Label));
timestamp.SetBinding(Label.ContentProperty, new Binding("Timestamp"));
FrameworkElementFactory from = new FrameworkElementFactory(typeof(Label));
from.SetBinding(Label.ContentProperty, new Binding("From"));
FrameworkElementFactory message = new FrameworkElementFactory(typeof(Label));
message.SetBinding(Label.ContentProperty, new Binding("Message"));
stackPanelFactory.AppendChild(timestamp);
stackPanelFactory.AppendChild(from);
stackPanelFactory.AppendChild(message);
dataTemplate.VisualTree = stackPanelFactory;
return dataTemplate;
}

How to get the clicked item from MpAndroidChart(UltimateXF) in Xamarin forms

I'm using MpAndroidChart(UltimateXF) for my app. I created the piechart successfully but I am unable to create a event listener to get the clicked item when user touched one of piechart item.
This is my UltimateXF library
https://nuget.org/packages/UltimateXF/
This is my code....
public partial class HomePage : ContentPage
{
public HomePage ()
{
InitializeComponent ();
var entries = new List<PieEntry>();
entries.Add(new PieEntry(40, "Life"));
entries.Add(new PieEntry(60, "General"));
var dataSet4 = new PieDataSet(entries, "")
{
Colors = new List<Color>()
{
Color.Accent, Color.Chocolate
},
ValueLineColor = Color.Blue,
SliceSpace = 2f,
ValueFormatter = new CustomPercentDataSetValueFormatter()
};
var data4 = new PieChartData(dataSet4)
{
};
var dataSet5 = new PieDataSet(entries, "")
{
};
pieChart.ChartData = data4;
pieChart.RotateEnabled = false;
}
}
public class CustomPercentDataSetValueFormatter : IDataSetValueFormatter
{
public string GetFormattedValue(float value, int dataSetIndex)
{
return value + "%";
}
}

Xamarin.Forms: NavigationController is null in PageRenderer

I am trying to use PageRenderer to customize/reposition elements of ToolbarItem for iOS but here NavigationController throwing null reference exception.
Below my code
public class MyNavigationRenderer: PageRenderer
{
public new MyNavigationBar Element
{
get { return (MyNavigationBar)base.Element; }
}
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
var LeftNavList = new List<UIBarButtonItem>();
var rightNavList = new List<UIBarButtonItem>();
var navigationItem = this.NavigationController.TopViewController.NavigationItem;
for (var i = 0; i < Element.ToolbarItems.Count; i++)
{
var reorder = (Element.ToolbarItems.Count - 1);
var ItemPriority = Element.ToolbarItems[reorder - i].Priority;
if (ItemPriority == 1)
{
UIBarButtonItem LeftNavItems = navigationItem.RightBarButtonItems[i];
LeftNavList.Add(LeftNavItems);
}
else if (ItemPriority == 0)
{
UIBarButtonItem RightNavItems = navigationItem.RightBarButtonItems[i];
rightNavList.Add(RightNavItems);
}
}
navigationItem.SetLeftBarButtonItems(LeftNavList.ToArray(), false);
navigationItem.SetRightBarButtonItems(rightNavList.ToArray(), false);
}
}
Below MyNavigationBar.cs class in portable/shared forms project
public class MyNavigationBar : NavigationPage
{
public MyNavigationBar(Page content) : base(content)
{
Init();
}
private void Init()
{
this.ToolbarItems.Add(new ToolbarItem() { Icon = "kid", Priority = 0, Order = ToolbarItemOrder.Primary });
this.ToolbarItems.Add(new ToolbarItem() { Text = "License", Priority = 0, Order = ToolbarItemOrder.Primary });
}
}
App starting
public App ()
{
InitializeComponent();
MainPage = new MyNavigationBar(new LoginPage());
}
See below screenshot getting exception
I faced this issue, but in my case, I was trying to get NavigationController from content page which didn't had NavigationController, make sure you null check before calling TopViewController,
var navController = this.NavigationController;
if(navController == null)
{
return;
}
UINavigationItem navigationItem = navController.TopViewController.NavigationItem;
For example,
When User opens the app, he will be presented with Login page, which didn't had any Navigation Bar.

Xamarin Forms add input field to each item of listview

I'm new to Xamarin Forms and I would want to add a input field (Numeric) on the right side of each item in my listview, so that I can type a quanty to my items. Somthing like a shopping list of items with the quantity of how many you want.
here is my code of my listview
List<string> item = new List<string>();
public MainPage()
{
InitializeComponent();
item.Add("Apple");
item.Add("Banana");
item.Add("Graps");
item.Add("Orange");
item.Add("Pineapple");
item.Add("Strawberry");
item.Add("Lemon");
item.Add("Mango");
item.Add("Cherry");
item.Add("Watermelon");
item.Add("Add");
var listView = new ListView
{
RowHeight = 40
};
listView.ItemsSource = item;
StackLayout layout = new StackLayout();
layout.Children.Add(listView);
listView.ItemSelected += (sender, e) =>
{
if (e.SelectedItem.ToString() == "Add")
{
var MyEntry = new Entry { Placeholder = "new item" };
layout.Children.Add(MyEntry);
MyEntry.Completed += MyEntry_Completed;
}
};
this.Content = layout;
}
private void MyEntry_Completed(object sender, EventArgs e)
{
var text = ((Entry)sender).Text;
item.Add(text);
}
I had a lot of trouble wrapping my head around databinding from the C# side in Xamarin Forms. I would recommend you checkout DataBinding to get a better understanding of this. I created a custom ViewCell for you to play around with, and a basic implementation so you can get a visual of how to implement it. You can adjust the view cell as much as needed. I just wanted to give you a bases of how to implement it. Hope this helps.
ViewCell
This is the view that displays for each list item in the list view.
using Xamarin.Forms;
namespace BountyApp.Controls
{
public class CustomViewCell : ViewCell
{
private Grid _grid = new Grid();
private Label _lbl = new Label() { HorizontalTextAlignment = TextAlignment.End, VerticalTextAlignment = TextAlignment.Center };
private Entry _entry = new Entry();
public CustomViewCell()
{
_lbl.SetBinding(Label.TextProperty, new Binding("Title"));
_grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.3, GridUnitType.Star) });
_grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.7, GridUnitType.Star) });
_grid.Children.Add(_lbl, 0, 0);
_grid.Children.Add(_entry, 1, 0);
View = _grid;
}
}
}
Implementing ViewCell
using Xamarin.Forms;
namespace BountyApp.Pages
{
public class ViewModel
{
public string Title { get; set; }
}
public class StepperPage : ContentPage
{
public ObservableCollection<ViewModel> List { get; set; }
public StepperPage()
{
List = new ObservableCollection<ViewModel>();
List.Add(new ViewModel { Title = "Apple" });
List.Add(new ViewModel { Title = "Banana" });
List.Add(new ViewModel { Title = "Graps" });
List.Add(new ViewModel { Title = "Orange" });
List.Add(new ViewModel { Title = "Pineapple" });
List.Add(new ViewModel { Title = "Strawberry" });
var listView = new ListView
{
RowHeight = 40,
ItemTemplate = new DataTemplate(typeof(CustomViewCell)),
ItemsSource = List
};
Content = listView;
}
}
}
Result

Why only the medium tile is getting updated?

I am writing a Windows 10 universal app in C# and i want to create a tile with a specific text on it that can change. Therefore I used the sample code form microsoft MSDN (the second one). But this does not work for all tiles, only the medium one shows the text "medium" on in, the others have just the app logo on it. I wonder what else is needed to force the other tiles to update.
This is the code I used to make the tile update:
public static void updateTile(){
TileContent content = new TileContent() {
Visual = new TileVisual() {
TileSmall = new TileBinding() {
Content = new TileBindingContentAdaptive() {
Children = {
new TileText() { Text = "Small" }
}
}
},
TileMedium = new TileBinding() {
Content = new TileBindingContentAdaptive() {
Children = {
new TileText() { Text = "Medium" }
}
}
},
TileWide = new TileBinding() {
Content = new TileBindingContentAdaptive() {
Children = {
new TileText() { Text = "Wide" }
}
}
},
TileLarge = new TileBinding() {
Content = new TileBindingContentAdaptive() {
Children = {
new TileText() { Text = "Large" }
}
}
}
}
};
// And then update the primary tile
TileUpdateManager.CreateTileUpdaterForApplication().Update(new TileNotification(content.GetXml()));
}

Categories