Nir*_*hta 9 ipad xamarin xamarin.forms
我是Xamarin.Forms的新手,并且遇到了一种情况,我想打开一个带有我的控件详细信息的弹出框[例如查看员工详细信息]点击父页面.
如何使用Xamarin.Forms打开自定义对话框/弹出窗口?
任何示例代码将不胜感激?
提前致谢!
Gab*_*bor 15
如果您仍希望将弹出窗口的代码放在自己的页面中,则可以按照以下逻辑设置一些自定义渲染器.
1. ModalPage和相应的渲染器
public class ModalPage : ContentPage { }
public class ModalPageRenderer : PageRenderer {
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
this.View.BackgroundColor = UIColor.Clear;
this.ModalPresentationStyle = UIModalPresentationStyle.OverCurrentContext;
}
public override void ViewDidLayoutSubviews()
{
base.ViewDidLayoutSubviews();
SetElementSize (new Size (View.Bounds.Width, View.Bounds.Height));
}
}
Run Code Online (Sandbox Code Playgroud)
2. HostPage
public class ModalHostPage : ContentPage, IModalHost
{
#region IModalHost implementation
public Task DisplayPageModal(Page page)
{
var displayEvent = DisplayPageModalRequested;
Task completion = null;
if (displayEvent != null)
{
var eventArgs = new DisplayPageModalRequestedEventArgs(page);
displayEvent(this, eventArgs);
completion = eventArgs.DisplayingPageTask;
}
// If there is no task, just create a new completed one
return completion ?? Task.FromResult<object>(null);
}
#endregion
public event EventHandler<DisplayPageModalRequestedEventArgs> DisplayPageModalRequested;
public sealed class DisplayPageModalRequestedEventArgs : EventArgs
{
public Task DisplayingPageTask { get; set;}
public Page PageToDisplay { get; }
public DisplayPageModalRequestedEventArgs(Page modalPage)
{
PageToDisplay = modalPage;
}
}
}
Run Code Online (Sandbox Code Playgroud)
3. HostPage渲染器
public class ModalHostPageRenderer: PageRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if(e.OldElement as ModalHostPage != null)
{
var hostPage = (ModalHostPage)e.OldElement;
hostPage.DisplayPageModalRequested -= OnDisplayPageModalRequested;
}
if (e.NewElement as ModalHostPage != null)
{
var hostPage = (ModalHostPage)e.NewElement;
hostPage.DisplayPageModalRequested += OnDisplayPageModalRequested;
}
}
void OnDisplayPageModalRequested(object sender, ModalHostPage.DisplayPageModalRequestedEventArgs e)
{
e.PageToDisplay.Parent = this.Element;
var renderer = RendererFactory.GetRenderer (e.PageToDisplay);
e.DisplayingPageTask = this.PresentViewControllerAsync(renderer.ViewController, true);
}
}
Run Code Online (Sandbox Code Playgroud)
然后就像await ModalHost.DisplayPageModal(new PopUpPage());
从主机页面调用一样简单,或者从后面的ViewModel 调用
此特定情况.
Pete所说的关于PushModalAsync/PopModalAsync的内容对于这个解决方案仍然有效(在我看来这不是一个缺点),但是你的弹出窗口会出现透明背景.
在我看来,这种方法的主要优点是,您可以将弹出式XAML /代码定义与主机页面分开,并在您希望显示该弹出窗口的任何其他页面上重复使用它.
您想要实现的一般目的可以通过使用Xamarin.Forms Navigation的PushModalAsync和PopModalAsync方法来实现 来实现。
很可能这足以满足您的需要 -但是- 这并不是真正的模态。我将在一小段代码之后进行解释:-
StackLayout objStackLayout = new StackLayout()
{
};
//
Button cmdButton_LaunchModalPage = new Button();
cmdButton_LaunchModalPage.Text = "Launch Modal Window";
objStackLayout.Children.Add(cmdButton_LaunchModalPage);
//
cmdButton_LaunchModalPage.Clicked += (async (o2, e2) =>
{
ContentPage objModalPage = new ContentPage();
objModalPage.Content = await CreatePageContent_Page2();
//
await Navigation.PushModalAsync(objModalPage);
//
// Code will get executed immediately here before the page is dismissed above.
});
//
return objStackLayout;
private async Task<StackLayout> CreatePageContent_Page2()
{
StackLayout objStackLayout = new StackLayout()
{
};
//
Button cmdButton_CloseModalPage = new Button();
cmdButton_CloseModalPage.Text = "Close";
objStackLayout.Children.Add(cmdButton_CloseModalPage);
//
cmdButton_CloseModalPage.Clicked += ((o2, e2) =>
{
this.Navigation.PopModalAsync();
});
//
return objStackLayout;
}
Run Code Online (Sandbox Code Playgroud)
上述问题的问题在于
await Navigation.PushModalAsync(objModalPage);
Run Code Online (Sandbox Code Playgroud)
动画结束后会立即返回。
尽管您无法与上一页进行交互,但由于我们正在显示一个新的导航页面并显示关闭按钮 -父 导航页面仍在幕后并行执行。
因此,如果您有任何计时器或任何执行的东西,除非您停止它们,否则它们仍然会被调用。
您还可以使用下面的文章中概述的TaskCompletionSource方法,以及如何使用 Xamarin.Forms 等待模态表单解除?。
请注意,虽然您现在可以等待第二页显示,然后当该页被关闭时允许代码在下一行继续执行,但这仍然不是真正的模态形式。同样,计时器或任何正在执行的内容都会在父页面上被调用。
更新 1:-
要使内容显示在现有内容的顶部,只需将其包含在当前页面上,但是在需要之前使这部分内容不可见。
如果您使用像Grid这样的外部容器,支持同一单元格中的多个子控件,那么您将能够实现您想要的。
您还需要使用类似具有透明度的填充框之类的东西,该框也将覆盖整个页面,以控制围绕内部内容部分的可见、透明部分。
归档时间: |
|
查看次数: |
15643 次 |
最近记录: |