需要修复:无法从 Listview-DataTemplate-ViewCell 内的自定义控件内的按钮打开模式
Need Fix: Cannot open modal from button inside a Custom control inside Listview-DataTemplate-ViewCell
我有一个奇怪的问题,但可能是因为我不明白。我创建了 2 个自定义控件。 [Custom Control A] 有一个名为 [LAUNCH] 的按钮,用于启动模式。 [自定义控件 B] 没有按钮,但里面有自定义控件 A。
我用 [Custom Control B] 创建了一个页面,但是当我单击 [LAUNCH] 时,在调试时它会转到代码行 await Navigation.PushModalAsync(new ModalPage()) 但在那之后,它不会启动模式。
我尝试添加 [Customer Control A] 并单击 [LAUNCH],它能够显示模式。
我需要做些什么才能从自定义控件 B 打开模式吗?
编辑:经过进一步检查,我忘了提及 [Custom Control B] 是我为列表视图的项目模板绑定的控件。我再次测试只是加载一个没有列表视图的 [Custom Control B] 并且它能够打开模态。但是,当我将它作为项目模板放回列表视图中时,问题仍然存在。我需要为此做些什么才能 运行 吗?还是不可能?
编辑 2:制作了一个新的示例项目并隔离了案例,看起来它确实阻止了模态打开。
[自定义控件 A]
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TestXamarin.Controls.CustomControlA">
<ContentView.Content>
<Grid BackgroundColor="AliceBlue" HeightRequest="300">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<FlexLayout Grid.Column="0"
Grid.Row="0"
Grid.RowSpan="2"/>
<Button x:Name="btnOpen"
Text="Try Open Modal"
Clicked="BtnOpen_Clicked"
Grid.Column="1"
Grid.Row="0"/>
</Grid>
</ContentView.Content>
</ContentView>
[自定义控件 A].cs
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class CustomControlA : ContentView
{
public CustomControlA()
{
InitializeComponent();
}
private async void BtnOpen_Clicked(object sender, EventArgs e)
{
await Navigation.PushModalAsync(new Modal());
}
}
[自定义控件 B]
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:TestXamarin.Controls"
x:Class="TestXamarin.Controls.CustomControlB">
<ContentView.Content>
<Frame BorderColor="Accent"
HeightRequest="300"
WidthRequest="300">
<controls:CustomControlA
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"></controls:CustomControlA>
</Frame>
</ContentView.Content>
</ContentView>
[自定义控件 B].cs
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class CustomControlB : ContentView
{
public CustomControlB()
{
InitializeComponent();
}
}
[主页]
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TestXamarin"
xmlns:controls="clr-namespace:TestXamarin.Controls"
x:Class="TestXamarin.MainPage">
<ListView x:Name="listSample"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<controls:CustomControlB/>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
[主页].cs
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
protected override void OnAppearing()
{
base.OnAppearing();
var list = Enumerable.Range(1, 10).ToList();
listSample.ItemsSource = list;
}
}
我找到了解决方案。看起来按钮只有在来自 ListView 项目的上下文时才有效。
所以我为自定义控件 A 和自定义控件 B 创建了一个命令绑定 属性,并在 ListView 项的 ViewModel 上创建了一个打开模态框的命令。然后我就可以通过命令打开模态了。
你也可以像这样调用推送模式页面(我认为它应该指定导航堆栈):
在您的 BtnOpen_Clicked 方法中:
private async void BtnOpen_Clicked(object sender, EventArgs e)
{
await App.Current.MainPage.Navigation.PushModalAsync(new Modal());
}
我有一个奇怪的问题,但可能是因为我不明白。我创建了 2 个自定义控件。 [Custom Control A] 有一个名为 [LAUNCH] 的按钮,用于启动模式。 [自定义控件 B] 没有按钮,但里面有自定义控件 A。
我用 [Custom Control B] 创建了一个页面,但是当我单击 [LAUNCH] 时,在调试时它会转到代码行 await Navigation.PushModalAsync(new ModalPage()) 但在那之后,它不会启动模式。
我尝试添加 [Customer Control A] 并单击 [LAUNCH],它能够显示模式。
我需要做些什么才能从自定义控件 B 打开模式吗?
编辑:经过进一步检查,我忘了提及 [Custom Control B] 是我为列表视图的项目模板绑定的控件。我再次测试只是加载一个没有列表视图的 [Custom Control B] 并且它能够打开模态。但是,当我将它作为项目模板放回列表视图中时,问题仍然存在。我需要为此做些什么才能 运行 吗?还是不可能?
编辑 2:制作了一个新的示例项目并隔离了案例,看起来它确实阻止了模态打开。
[自定义控件 A]
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TestXamarin.Controls.CustomControlA">
<ContentView.Content>
<Grid BackgroundColor="AliceBlue" HeightRequest="300">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<FlexLayout Grid.Column="0"
Grid.Row="0"
Grid.RowSpan="2"/>
<Button x:Name="btnOpen"
Text="Try Open Modal"
Clicked="BtnOpen_Clicked"
Grid.Column="1"
Grid.Row="0"/>
</Grid>
</ContentView.Content>
</ContentView>
[自定义控件 A].cs
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class CustomControlA : ContentView
{
public CustomControlA()
{
InitializeComponent();
}
private async void BtnOpen_Clicked(object sender, EventArgs e)
{
await Navigation.PushModalAsync(new Modal());
}
}
[自定义控件 B]
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:TestXamarin.Controls"
x:Class="TestXamarin.Controls.CustomControlB">
<ContentView.Content>
<Frame BorderColor="Accent"
HeightRequest="300"
WidthRequest="300">
<controls:CustomControlA
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"></controls:CustomControlA>
</Frame>
</ContentView.Content>
</ContentView>
[自定义控件 B].cs
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class CustomControlB : ContentView
{
public CustomControlB()
{
InitializeComponent();
}
}
[主页]
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TestXamarin"
xmlns:controls="clr-namespace:TestXamarin.Controls"
x:Class="TestXamarin.MainPage">
<ListView x:Name="listSample"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<controls:CustomControlB/>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
[主页].cs
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
protected override void OnAppearing()
{
base.OnAppearing();
var list = Enumerable.Range(1, 10).ToList();
listSample.ItemsSource = list;
}
}
我找到了解决方案。看起来按钮只有在来自 ListView 项目的上下文时才有效。
所以我为自定义控件 A 和自定义控件 B 创建了一个命令绑定 属性,并在 ListView 项的 ViewModel 上创建了一个打开模态框的命令。然后我就可以通过命令打开模态了。
你也可以像这样调用推送模式页面(我认为它应该指定导航堆栈):
在您的 BtnOpen_Clicked 方法中:
private async void BtnOpen_Clicked(object sender, EventArgs e)
{
await App.Current.MainPage.Navigation.PushModalAsync(new Modal());
}