Xamarin.forms SwitchCell Text Does not appear fully - c#

I am newer with Xamarin.Forms. Is there a way to display all text an a SwitchCell? The long text get's cut off.
NewsLetterSwitchCell = new SwitchCell
{
Text="abcdefghijklmnopqrstvwxyz123456789aabbccdeeffgghhjjkkllmmmnnooppqqrrsssrtg",
};
NewsLetterSwitchCell.OnChanged += switcher_Toggled;
TableView tb = new TableView();
tb.Root = new TableRoot() {
new TableSection("Enter Optional Information (* Required Fields)") {
NewsLetterSwitchCell
}
};
Content = new StackLayout
{
Children = { tb }
};
This Picture shows the result from my mobile. It contains only the first letters.

You need to write your own custom renderer for this purpose .
Below link can help you .
Forum link for custom switch

Related

Adaptive card action button text & UI trimmed inside the MS Team Channel

I'm having an issue where buttons and actions in ms teams adaptive cards won’t wrap text inside the action button. The button UI is completely broken even if we are applied " full: width" in MS Team. I know the "Wrap: true || false" we can add inside the adaptive card body or title of the textblock, Is there any other way to handle this type of scenario in the action button title in MS Team channel.
The following code we are using for the adaptive card implementation.
public static Attachment ChoiceMenu(string channelType, string text, List buttons, string subCategory = null)
{
var menuCard = new AdaptiveCard("1.2");
if(!string.IsNullOrEmpty(subCategory))
{
menuCard.Body.Add(new AdaptiveTextBlock()
{
Text = subCategory,
Size = AdaptiveTextSize.Large,
Wrap = true,
});
}
menuCard.Body.Add(new AdaptiveTextBlock()
{
Text = text,
Wrap = true,
});
foreach (var button in buttons)
{
var columns = new AdaptiveColumnSet();
menuCard.Body.Add(columns);
var userCategory = new AdaptiveColumn();
columns.Columns.Add(userCategory);
var actionType = new AdaptiveActionSet();
userCategory.Items.Add(actionType);
var submitAction = new AdaptiveSubmitAction()
{
Title = button,
Id = button
};
if (channelType == Channels.Msteams)
{
submitAction.Data = new AdaptiveCardDataObjectForTeams()
{
MsTeams = new MsTeamsObject()
{
Type = ActionTypes.MessageBack,
DisplayText = button,
Text = button
}
};
}
else
{
submitAction.Data = button;
}
actionType.Actions.Add(submitAction);
}
return new Attachment()
{
ContentType = AdaptiveCard.ContentType,
Content = menuCard
};
}
Platform
Web ( MsTeams Web http://teams.microsoft.com ) Microsoft Teams
Version 1.4.00.32771 (64-bit). It was last updated on 12/15/2021.
Adaptive Card Version
1.2
As per the Format cards in Microsoft Teams docs,
Cards support formatting in the text property only, not in the title
or subtitle properties.
Note: The Action Button text is in the title property, This is the reason we cannot do any formatting for it. So there is no way to wrap text in the Action Button.
Alternate Solution:
We have changed the MS Team title of the button using the substring concatenation, hereafter the particular character will display "...", So this way we can alternatively fix this issue.
submitAction.Title = button.Length > 50 ? string.Concat(button.Substring(0, 50), "...") : button;
Output:
Reference:
Github discussion
Apart from using full width property in Adaptive card, there doesn't seem to be any way to increase the size of actionable buttons in adaptive card in order to fit the text/title properly.
"msteams": {
"width": "Full"
}

How to add a TapGestureRecognizer with c# to created items from JSON?

so Im trying to Deserialize a JSON file and creat some items from it, so far everything is working well. My problem is that i want to add a TapGestureRecognizer to each item created and i don't know how to do so.
List<Categories> categorie = JsonConvert.DeserializeObject<List<Categories>>(categoriejson);
Device.BeginInvokeOnMainThread(() =>
{
foreach (Categories c in categorie)
{
Image image = new Image
{
Source = ImageSource.FromUri(new Uri(c.imageUrl))
};
image.HeightRequest = 105;
CategorieLayout.Children.Add(image);
so I just want to add a tap gesture to each created image. I was thinking about checking the x:name given by default to each image, but i failed to do that to ... any ideas are going to be much appreciated.
something like this should work - I'm doing this from memory so the syntax may not be perfect
Image image = new Image
{
Source = ImageSource.FromUri(new Uri(c.imageUrl))
};
var tap = new TappedGestureRecognizer();
tap.Tapped += TappedHandler;
image.GestureRecognizers.Add(tap);
If you are trying to deserialize a JSON file and creat some items from it,I suggest you use a ScrollView to wrap the content.It is likely that one page will not be displayed completely and scrolling is required.YOu can do like this:
public TestPage1()
{
StackLayout stackLayout = new StackLayout{};
ScrollView scroll = new ScrollView();
scroll.Content = stackLayout;
foreach (Categories c in categorie) {
var image = new Image
{
Source = ImageSource.FromUri(new Uri(c.imageUrl))
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.CenterAndExpand,
};
var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.Tapped += Image_OnTapped;
image.ClassId = c.imageUrl;//attach data to image's `ClassId`
image.GestureRecognizers.Add(tapGestureRecognizer);
stackLayout.Children.Add(image);
}
Content = scroll;
}
Method Image_OnTapped
private void Image_OnTapped(object sender, EventArgs e)
{
// retrieve parameter from sender's ClassId
var parm = ((Image)sender).ClassId;
}
Note:
The sender of the Tapped event will be the control which the gesturerecognizer is attached to. in your case, an Image. You can attach your data to one of the Image's properties in order to access it from your event handler.
image.ClassId = c.imageUrl;//attach data to image's `ClassId`
And get value from method Image_OnTapped like this:
var parm = ((Image)sender).ClassId;

Create Multiple Labels in Data Template

I have created a data template to use within a list view. This will later be expanded to add more content to each item in this list view. At the moment all the items that are bound to the observable collection are working as expected, except for one.
In each instance of the data template the bound properties are height, RouteName and routeStops. The height and RouteName are working fine but I'm not sure how to bind the routeStops correctly.
For each one of the RouteNames there are multiple stops, so for each data template use there must be one label that has the RouteName and multiple labels for each stop on the route (using routeStops).
I am not entirely sure how to achieve this, I can only seem to bind one stop to one label. I want to create them dynamically to allow for any amount of stops.
So the code behind that creates the data template (Just the constructor):
public MainRoutePageViewDetail(MessagDatabase database)
{
InitializeComponent();
BindingContext = mainroutepageviewmodel = new MainRoutePageViewModel(database,Navigation);
StackLayout mainstack = new StackLayout();
var routelisttemplate = new DataTemplate(() => {
ViewCell viewcell = new ViewCell();
stacklayout = new StackLayout();
stacklayout.SetBinding(StackLayout.HeightRequestProperty,"height");
viewcell.View = stacklayout;
// labels for template
var nameLabel = new Label { FontAttributes = FontAttributes.Bold, BackgroundColor = Color.LightGray };
nameLabel.HorizontalOptions = LayoutOptions.Center;
nameLabel.VerticalOptions = LayoutOptions.Center;
nameLabel.SetBinding(Label.TextProperty, "RouteName");
//inforLabel.SetBinding(Label.TextProperty, "Stops");
stacklayout.Children.Add(nameLabel);
StackLayout nextstack = new StackLayout();
var nameLabel2 = new Label { FontAttributes = FontAttributes.Bold, BackgroundColor = Color.Red };
nameLabel2.HorizontalOptions = LayoutOptions.Center;
nameLabel2.VerticalOptions = LayoutOptions.Center;
nameLabel2.SetBinding(Label.TextProperty, "routeStops");
nextstack.Children.Add(nameLabel2);
stacklayout.Children.Add(nextstack);
return viewcell;
});
ListView listviewofroutes = new ListView();
mainstack.Children.Add(listviewofroutes);
listviewofroutes.SetBinding(ListView.ItemsSourceProperty, "routeLabels");
listviewofroutes.ItemTemplate = routelisttemplate;
listviewofroutes.HasUnevenRows = true;
Content = mainstack;
}// end of constructor
This is bound to an ObservableCollection in the view model. Im going to leave this out as its irrelevant because the bindings work fine.
This calls down to functions in the model that collect data from SQL tables.
The function in the model that collects data:
public List<RouteInfo> getrouteInfo()
{
var DataBaseSelection = _connection.Query<RouteInfoTable>("Select * From [RouteInfoTable]");
List<RouteInfo> dataList = new List<RouteInfo>();
for (var i = 0; i < DataBaseSelection.Count; i++)
{
var DataBaseSelection2 = _connection.Query<RouteStopsTable>("Select StopOnRoute From [RouteStopsTable] WHERE RouteName = ? ",DataBaseSelection[i].RouteName);
dataList.Add(new RouteInfo
{
ID = DataBaseSelection[i].ID,
RouteName = DataBaseSelection[i].RouteName,
Stops = DataBaseSelection[i].Stops,
DayOf = DataBaseSelection[i].DayOf,
IsVisible = DataBaseSelection[i].IsVisible,
routeStops = DataBaseSelection2[i].StopOnRoute,
height = 200
});
}
return dataList;
}
The first table (RouteInfoTable) gets RouteName and some other information and the second table gets the stops on the route using the RouteName as a key. This is all added to a list of RouteInfo instances.
DataBaseSelection2 grabs all of the stops on the route but only one of them displays. I know why this is but I dont know how to display all three.
The Table definitions and class definitions as well as the selections from the tables are not an issue. I have debugged these and they are getting the correct information I just dont know how to display it on the front end in the way I want to. Here is a visual of what I mean if its getting complicated:
The best I can do is one route stop not all three.
An ideas how to achieve this?
Sorry if its complicated.
You can use Grouping in ListView to achieve this visual. Basically in this case you will be defining two DataTemplate(s) -
GroupHeaderTemplate for RouteName
ItemTemplate for StopsOnRoute.

Changing Xamarin Label in ListCell does not work

I have a problem with a ListView. I want each Cell to have a label and a switch but the text of the label does not appear.
Here is my code:
public class FilterPage : ContentPage
{
public FilterPage()
{
List<FilterCell> listContent = new List<FilterCell>();
foreach(string type in Database.RestaurantTypes)
{
FilterCell fc = new FilterCell();
fc.Text = type;
listContent.Add(fc);
}
ListView types = new ListView();
types.ItemTemplate = new DataTemplate(typeof(FilterCell));
types.ItemsSource = listContent;
var layout = new StackLayout();
layout.Children.Add(types);
Content = layout;
}
}
public class FilterCell : ViewCell
{
private Label label;
public Switch CellSwitch { get; private set; }
public String Text{ get { return label.Text; } set { label.Text = value; } }
public FilterCell()
{
label = new Label();
CellSwitch = new Switch();
var layout = new StackLayout
{
Padding = new Thickness(20, 0, 0, 0),
Orientation = StackOrientation.Horizontal,
HorizontalOptions = LayoutOptions.FillAndExpand,
Children = { label, CellSwitch }
};
View = layout;
}
}
If I enter a fixed Text in the FilterCell-Constructor it works fine (e.g.: label.Text = "Hello World")
When I create a Method for the ItemSelected-Event and read out the SelectedItem.Text Property I get the text I assigned as Value but it's never displayed. Only the switch is displayed when I try to run this Code.
Thanks for your help
Niko
Ohh boy. This code looks like a rape (sorry I had to say this).
Now let's see what's wrong:
The reason is you are mixing up data and view heavily.
The line
types.ItemTemplate = new DataTemplate(typeof(FilterCell));
means: "For each item in the list (ItemsSource) create a new filter cell". The FilterCells that you create in the loop are never displayed.
The easy fix
public class FilterPage : ContentPage
{
public FilterPage()
{
var restaurantTypes = new[] {"Pizza", "China", "German"}; // Database.RestaurantTypes
ListView types = new ListView();
types.ItemTemplate = new DataTemplate(() =>
{
var cell = new SwitchCell();
cell.SetBinding(SwitchCell.TextProperty, ".");
return cell;
});
types.ItemsSource = restaurantTypes;
Content = types;
}
}
There is a standard cell type that contains a label and a switch SwitchCell, use it.
As ItemsSource of your list, you have to use your data. In your case the list of restaurant types. I just mocked them with a static list.
The DataTemplate creates the SwitchCell and sets the Databinding for the Text property. This is the magic glue between View and data. The "." binds it to the data item itself. We use it, because our list contains items of strings and the Text should be exactly the string. (read about Databinding: https://developer.xamarin.com/guides/xamarin-forms/getting-started/introduction-to-xamarin-forms/#Data_Binding )
I striped away the StackLayout that contained the list. You can directly set the list as Content of the page.
Lesson
use standard controls, if possible
You should always try to remember to keep data and view apart from each other and use data binding to connect to each other.
Try to avoid unnecessary views.

DevExpress Reports different watermark image on 2 pages or alternative?

I am creating a report with DevExpress in VS2013 and I need to create it according to a template. The report consists of 2 pages which need to display an image of a page from a PDF en then display data accordingly.
In my first attempt I created 2 report with their according watermark images and then added the second report to the first programmatically.
if (reportModel.Report is RequestBonusPage1)
{
var tweedePagina = new RequestBonusPage2();
secondPage.CreateDocument();
reportModel.Report.Pages.AddRange(secondPage.Pages);
}
If I create the report this way the data needed to display on the second page doesn't get passed, hard coded labels are. Also the watermark image itself is not displayed even though I have the DrawWatermark property set to true.
With my second attempt I removed the watermark image from the second page and added the image with a Picturebox but the labels with the data are then displayed next to the picturebox. I used this link (https://www.devexpress.com/Support/Center/Question/Details/Q323059) as an example for doing this.
Does anyone how I can make these examples work or know any alternatives as of how to achieve this?
If anything is unclear about my explanation don't be afraid to ask.
Kind regards
EDIT:
public ActionResult ExportDocumentViewer()
{
var reportModel = BuildReportModel(ModelSessionHelper.CurrentReportData);
ProcessSpecificReport(reportModel);
return DevExpress.Web.Mvc.DocumentViewerExtension.ExportTo(reportModel.Report);
}
private static void ProcessSpecificReport(ReportModel reportModel)
{
reportModel.Report.CreateDocument();
if (reportModel.Report is SalesReport)
{
var secondPage = new SalesReportPage2();
secondPage.CreateDocument();
reportModel.Report.Pages.AddRange(secondPage.Pages);
}
if (reportModel.Report is RequestBonusPage1)
{
var secondPage = new RequestBonusPage2();
secondPage.SetReportData(reportModel.ReportData);
secondPage.DrawWatermark = true;
secondPage.CreateDocument();
reportModel.Report.Pages.AddRange(secondPage.Pages);
CreateWatermarkRequestBonus(reportModel);
}
}
private static void CreateWatermarkRequestBonus(ReportModel model)
{
model.Report.Pages[0].AssignWatermark(new Watermark
{
Image = Properties.Resources.bonus_request_page_001,
ImageViewMode = ImageViewMode.Zoom,
PageRange = "1",
});
model.Report.Pages[1].AssignWatermark(new Watermark
{
Image = Properties.Resources.bonus_request_page_002,
ImageViewMode = ImageViewMode.Zoom,
PageRange = "2",
});
}
You can use Page.AssignWatermark method to set the watermark for particular page.
Here is example:
var report = new YourReportClass();
//...
report.CreateDocument();
var page = report.Pages[0];
var watermark = new Watermark();
watermark.Text = "Watermark text";
watermark.TextDirection = DirectionMode.ForwardDiagonal;
page.AssignWatermark(watermark);
report.ShowRibbonPreview();

Categories