I have gone through several Q&A here and on different portals but cannot get this working...
My page orientation is Portrait...
<Rectangle x:Name="videoRectangle" Margin="0,0,0,0">
<Rectangle.Fill>
<VideoBrush x:Name="viewfinderBrush" AlignmentX="Left" AlignmentY="Top" Stretch="UniformToFill">
<VideoBrush.RelativeTransform>
<CompositeTransform x:Name="videoBrushTransform" CenterX="0.5" CenterY="0.5" />
</VideoBrush.RelativeTransform>
</VideoBrush>
</Rectangle.Fill>
</Rectangle>
the code behind ARPage_OrientationChanged never gets invoked
public ARPage()
{
InitializeComponent();
this.OrientationChanged += ARPage_OrientationChanged;
}
void ARPage_OrientationChanged(object sender, OrientationChangedEventArgs e)
{
abc.Text = e.Orientation.ToString();
switch (e.Orientation)
{
case PageOrientation.Landscape:
case PageOrientation.LandscapeLeft:
videoBrushTransform.Rotation = 0;
break;
case PageOrientation.LandscapeRight:
videoBrushTransform.Rotation = -45;
break;
case PageOrientation.Portrait:
case PageOrientation.PortraitUp:
videoBrushTransform.Rotation = -270;
break;
case PageOrientation.PortraitDown:
videoBrushTransform.Rotation = -90;
break;
}
}
The video brush always show video in landscape mode...
what i am doing wrong
it is not necessary to assign the event in the constructor, you can do this:
public ARPage()
{
InitializeComponent();
}
protected override void OnOrientationChanged(OrientationChangedEventArgs e)
{
abc.Text = e.Orientation.ToString();
switch (e.Orientation)
{
case PageOrientation.Landscape:
case PageOrientation.LandscapeLeft:
videoBrushTransform.Rotation = 0;
break;
case PageOrientation.LandscapeRight:
videoBrushTransform.Rotation = -45;
break;
case PageOrientation.Portrait:
case PageOrientation.PortraitUp:
videoBrushTransform.Rotation = -270;
break;
case PageOrientation.PortraitDown:
videoBrushTransform.Rotation = -90;
break;
}
base.OnOrientationChanged(e);
}
Related
I want to be able to set a property of a MudBlazor Date Picker component based on breakpoint. I can only think of having 2 versions and hiding one or the other but I am hoping there is a cleaner way.
And more generally is there an easy way to detect in the #code section what breakpoint the user is in?
You can use IBreakpointService
here is an example of changing the DateTime picker value by changing the breakpoint.
https://try.mudblazor.com/snippet/GkwcklvshoBJfwUS
#using MudBlazor.Services
<MudCard Class="pa-5">
<MudDatePicker #bind-Date="_dateTime"/>
</MudCard>
#code {
private DateTime? _dateTime { get; set; } = DateTime.Now;
[Inject] IBreakpointService BreakpointListener { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await BreakpointListener.Subscribe(breakpoint =>
{
switch (breakpoint)
{
case Breakpoint.Xs:
_dateTime = DateTime.Now.AddDays(1);
break;
case Breakpoint.Sm:
_dateTime = DateTime.Now.AddDays(2);
break;
case Breakpoint.Md:
_dateTime = DateTime.Now.AddDays(3);
break;
case Breakpoint.Lg:
_dateTime = DateTime.Now.AddDays(4);
break;
case Breakpoint.Xl:
_dateTime = DateTime.Now.AddDays(5);
break;
case Breakpoint.Xxl:
_dateTime = DateTime.Now.AddDays(6);
break;
case Breakpoint.SmAndDown:
_dateTime = DateTime.Now.AddDays(7);
break;
case Breakpoint.MdAndDown:
_dateTime = DateTime.Now.AddDays(8);
break;
case Breakpoint.LgAndDown:
_dateTime = DateTime.Now.AddDays(9);
break;
case Breakpoint.XlAndDown:
_dateTime = DateTime.Now.AddDays(10);
break;
case Breakpoint.SmAndUp:
_dateTime = DateTime.Now.AddDays(11);
break;
case Breakpoint.MdAndUp:
_dateTime = DateTime.Now.AddDays(12);
break;
case Breakpoint.LgAndUp:
_dateTime = DateTime.Now.AddDays(13);
break;
case Breakpoint.XlAndUp:
_dateTime = DateTime.Now.AddDays(14);
break;
case Breakpoint.None:
_dateTime = DateTime.Now.AddDays(15);
break;
case Breakpoint.Always:
_dateTime = DateTime.Now.AddDays(16);
break;
}
InvokeAsync(StateHasChanged);
});
StateHasChanged();
}
await base.OnAfterRenderAsync(firstRender);
}
}
Skiasharp enables to manipulate touch events with the method:
private void OnTouch(object sender, SKTouchEventArgs args)
With this method I can handle only one touch point coordinates:
args.Location.X, args.Location.Y
But how can I detect multitouch event?
The Android native API for example enables you to manage two finger locations in order to detect multitouch.
How can I achieve that with SkiaSharp?
Ok, I found a solution for my question here is the code.
//Multitouch handling
Dictionary<long, SKPoint> dragDictionary = new Dictionary<long, SKPoint>();
private void OnTouch(object sender, SKTouchEventArgs e)
{
switch (e.ActionType)
{
case SKTouchAction.Pressed:
dragDictionary[e.Id] = e.Location;
break;
case SKTouchAction.Entered:
break;
case SKTouchAction.Moved:
if (dragDictionary.Keys.Count > 1)
{
dragDictionary[e.Id] = e.Location;
SKPoint? p1 = null;
SKPoint? p2 = null;
foreach (long key in dragDictionary.Keys)
{
if (p1 == null)
{
p1 = dragDictionary[key];
}
else if (p2 == null)
{
p2 = dragDictionary[key];
}
}
//MultiTouch handle
}
else
{
//SingleTouch handle
}
break;
case SKTouchAction.Released:
dragDictionary.Remove(e.Id);
break;
case SKTouchAction.Exited:
break;
}
// we have handled these events
e.Handled = true;
((SKCanvasView)sender).InvalidateSurface();
}
How to?
I tried these two methods, but none works. The first hangs, the second quits the program (without any exception).
private void ApplicationClosing1(object sender, ApplicationClosingEventArgs e)
{
MessageResult result = MessageResult.None;
if (!isClosing && IsDirty)
{
result = MessageService.ShowAsync("blah", "blah",
MessageButton.YesNoCancel, MessageImage.Warning)
.GetAwaiter().GetResult();
switch (result)
{
case MessageResult.Cancel:
e.Cancel = true;
return;
case MessageResult.Yes:
isClosing = true;
SaveAsync();
break;
default:
isClosing = true;
break;
}
}
}
and
private async void ApplicationClosing2(object sender, ApplicationClosingEventArgs e)
{
if (!isClosing && IsDirty)
{
var result = await MessageService.ShowAsync("blah","blah",
MessageButton.YesNoCancel, MessageImage.Warning);
switch (result)
{
case MessageResult.Cancel:
e.Cancel = true;
return;
case MessageResult.Yes:
isClosing = true;
await SaveAsync();
break;
default:
isClosing = true;
break;
}
}
}
You could solve it the same way as the DataWindows takes care of this. First set e.Cancel = true, then if the user answers, set an internal bool _reallyClose and don't set e.Cancel when this is true.
i'm trying to implement a NSTableView in my project and fill it with specific data. This works quite fine. But now, i want to be able, to hide some columns, color specific cells, or color specific rows. I made something similar in java, but i really don't know to to do this in Xamarin:Mac.
Here is the code for my delegate:
public class Mp3FileTableDelegate : NSTableViewDelegate {
private const string CellIdentifier = "FileCell";
private Mp3FileDataSource DataSource;
public Mp3FileTableDelegate (Mp3FileDataSource datasource) {
this.DataSource = datasource;
}
public override NSView GetViewForItem (NSTableView tableView, NSTableColumn tableColumn, nint row) {
// This pattern allows you reuse existing views when they are no-longer in use.
// If the returned view is null, you instance up a new view
// If a non-null view is returned, you modify it enough to reflect the new data
NSTextField view = (NSTextField)tableView.MakeView (CellIdentifier, this);
if (view == null) {
view = new NSTextField ();
view.Identifier = CellIdentifier;
view.BackgroundColor = NSColor.Clear;
view.Bordered = false;
view.Selectable = false;
view.Editable = true;
view.EditingEnded += (sender, e) => {
SetNewValueInMp3File (DataSource.AudioFiles [(int)row], tableColumn, view.StringValue);
};
}
AudioFile audioFile = DataSource.AudioFiles [(int)row];
// Setup view based on the column selected
switch (tableColumn.Title) {
case "Path":
view.StringValue = audioFile.getPathWithFilename ();
break;
}
if (audioFile.GetType () == typeof(Mp3File)) {
Mp3File mp3File = (Mp3File)audioFile;
switch (tableColumn.Title) {
case "Artist":
view.StringValue = mp3File.Artist;
break;
case "Title":
view.StringValue = mp3File.Title;
break;
case "Album":
view.StringValue = mp3File.Album;
break;
case "BPM":
view.StringValue = mp3File.BPM;
break;
case "Comment":
view.StringValue = mp3File.Comment;
break;
case "Year":
view.StringValue = mp3File.Year;
break;
case "Key":
view.StringValue = mp3File.InitialKey;
break;
case "Quality":
view.StringValue = mp3File.Album;
break;
case "Length":
view.StringValue = mp3File.Album;
break;
}
}
return view;
}
private void SetNewValueInMp3File (AudioFile file, NSTableColumn tableColumn, String value) {
if (file.GetType () == typeof(Mp3File)) {
Mp3File mp3File = (Mp3File)file;
switch (tableColumn.Title) {
case "Artist":
mp3File.Artist = value;
break;
case "Title":
mp3File.Title = value;
break;
case "Album":
mp3File.Album = value;
break;
case "BPM":
mp3File.BPM = value;
break;
case "Comment":
mp3File.Comment = value;
break;
case "Year":
mp3File.Year = value;
break;
case "Key":
mp3File.InitialKey = value;
break;
}
}
}
}
And here for my datasource:
public class Mp3FileDataSource : NSTableViewDataSource {
public List<AudioFile> AudioFiles = new List<AudioFile> ();
public Mp3FileDataSource () {
}
public override nint GetRowCount (NSTableView tableView) {
return AudioFiles.Count;
}
}
I would be very thankful, if anyone could help me a little.
Thanks
Is there a way to conditionally load different user control as edit form based on some user action (Edit vs. Create)?
This is how I ended up doing it
protected void Page_Init(object sender, EventArgs e)
{
ctlBenefitLimitsGrid.MasterTableView.EditFormSettings.EditFormType = GridEditFormType.WebUserControl;
ctlBenefitLimitsGrid.ItemDataBound += BenefitLimitsGrid_ItemDataBound;
ctlBenefitLimitsGrid.ItemCommand += BenefitLimitsGrid_ItemCommand;
ctlBenefitLimitsGrid.MasterTableView.EditFormSettings.EditFormType = GridEditFormType.WebUserControl;
}
void BenefitLimitsGrid_ItemCommand(object source, GridCommandEventArgs e)
{
switch (e.CommandName)
{
case "Edit":
e.Item.OwnerTableView.IsItemInserted = false;
ctlBenefitLimitsGrid.MasterTableView.EditFormSettings.UserControlName =
#"UserControls/BenefitLimitEdit.ascx";
break;
case "Add":
{
InsertAddControl(e);
break;
}
case "Delete":
var benefitLimitId = Convert.ToInt32(e.CommandArgument);
Presenter.Delete(benefitLimitId);
Presenter.LoadView();
break;
case "Save":
IEditView item;
if (e.Item.GetType() == typeof(GridEditFormInsertItem))
{
item =
(IEditView)e.Item.FindControl(GridEditFormItem.EditFormUserControlID);
}
else
{
item = ((GridDataItem)e.Item).EditFormItem.FindControl(GridEditFormItem.EditFormUserControlID) as IEditView;
}
if (item != null && item.HasErrors)
{
e.Canceled = true;
return;
}
e.Item.Edit = false;
ctlBenefitLimitsGrid.MasterTableView.ClearEditItems();
Presenter.LoadView();
break;
case "SaveAndNew":
{
var benefitLimitCreate = (IBenefitLimitCreate)e.Item.FindControl(GridEditFormItem.EditFormUserControlID);
if (benefitLimitCreate.HasErrors)
{
e.Canceled = true;
return;
}
Presenter.LoadView();
InsertAddControl(e);
break;
}
}
}
private void InsertAddControl(GridCommandEventArgs e)
{
ctlBenefitLimitsGrid.MasterTableView.ClearEditItems();
ctlBenefitLimitsGrid.MasterTableView.EditFormSettings.UserControlName = #"UserControls/BenefitLimitCreate.ascx";
e.Item.OwnerTableView.InsertItem();
var insertedItem = e.Item.OwnerTableView.GetInsertItem();
var ctlBenefitLimitCreate = (BenefitLimitCreate)insertedItem.FindControl(GridEditFormItem.EditFormUserControlID);
ctlBenefitLimitCreate.Presenter.LoadView();
}
I think that there was an article in the Telerik online documentation (under Insert/Update/Delete -> HowTo chapter) which does exactly what you are after.
Dick