模板 10:模态不关闭
Template 10: Modal not closing
我想在 Shell 视图中使用模态中的按钮关闭模板 10 的模态。 Shell.xaml.cs 中的关闭函数被触发,IsModal 和 HasError 被切换为 false,但模态对话框保持活动状态。
我使用的代码:
LandingpageViewModel:
public override async void OnNavigatedTo(object parameter, NavigationMode mode, IDictionary<string, object> state)
{
var i = await getMuscleScores();
if(i == null)
ShowError();
}
public void ShowError()
{
Views.Shell.SetError(true);
}
Shell.xaml.cs:
public bool IsModal { get; set; } = false;
public bool HasError { get; set; } = false;
public string ErrorText { get; set; } = "Something went wrong...";
public static void SetError(bool error, string text = null)
{
WindowWrapper.Current().Dispatcher.Dispatch(() =>
{
if (error)
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Collapsed;
else
BootStrapper.Current.UpdateShellBackButton();
Instance.IsModal = error;
Instance.IsBusy = !error;
Instance.HasError = error;
Instance.ErrorText = text == null ? "Something went wrong..." : text;
Instance.PropertyChanged?.Invoke(Instance, new PropertyChangedEventArgs(nameof(IsModal)));
Instance.PropertyChanged?.Invoke(Instance, new PropertyChangedEventArgs(nameof(HasError)));
Instance.PropertyChanged?.Invoke(Instance, new PropertyChangedEventArgs(nameof(ErrorText)));
});
}
public void HideError(object sender, TappedRoutedEventArgs e)
{
SetError(false);
}
Shell.xaml:
<Controls:ModalDialog.ModalContent>
<Grid>
<Viewbox Height="32">
<StackPanel Orientation="Horizontal" Visibility="{x:Bind IsBusy, Mode=OneWay, Converter={StaticResource visibilityConv}}">
<ProgressRing Width="16" Height="16"
Margin="12,0" Foreground="White"
IsActive="{x:Bind IsBusy, Mode=OneWay}" />
<TextBlock VerticalAlignment="Center" Foreground="White" Text="{x:Bind BusyText, Mode=OneWay}" />
</StackPanel>
</Viewbox>
<StackPanel Visibility="{x:Bind HasError, Mode=OneWay, Converter={StaticResource visibilityConv}}" VerticalAlignment="Center" Margin="12,0">
<TextBlock Text="Oops!" Style="{ThemeResource HeaderTextBlockStyle}"/>
<TextBlock Text="{x:Bind ErrorText, Mode=OneWay}"/>
<Button Content="Continue" Style="{StaticResource ButtonStyle}" HorizontalAlignment="Center" Tapped="HideError"/>
</StackPanel>
</Grid>
</Controls:ModalDialog.ModalContent>
我试图找到问题的另一件事是 LandingPageViewModel:
ShowError();
await Task.Delay(5000);
HideError();
这给我的结果与模式对话框保持打开状态相同。所以我认为使用不同的线程似乎出了问题。有人知道这个问题的解决方案吗?顺便说一句:我使用的是最新版本的模板 10
在此处输入代码
要关闭Template 10 的模态,我们需要将ModalDialog.IsModal
属性 设置为"false"。由于您的 XAML 代码不完整,我猜您使用的是 Template 10 Minimal 模板。在模板中它使用 IsBusy
设置 ModalDialog.IsModal
属性。但似乎您在代码隐藏中使用 IsModal
来控制 ModalDialog
,因此您可以将此 属性 绑定到 ModalDialog.IsModal
,如下所示:
<Controls:ModalDialog IsModal="{x:Bind IsModal, Mode=OneWay}">
<Controls:ModalDialog.Content>
...
</Controls:ModalDialog.Content>
<Controls:ModalDialog.ModalContent>
<Grid>
<Viewbox Height="32">
<StackPanel Orientation="Horizontal" Visibility="{x:Bind IsBusy, Mode=OneWay, Converter={StaticResource visibilityConv}}">
<ProgressRing Width="16" Height="16"
Margin="12,0" Foreground="White"
IsActive="{x:Bind IsBusy, Mode=OneWay}" />
<TextBlock VerticalAlignment="Center" Foreground="White" Text="{x:Bind BusyText, Mode=OneWay}" />
</StackPanel>
</Viewbox>
<StackPanel Visibility="{x:Bind HasError, Mode=OneWay, Converter={StaticResource visibilityConv}}" VerticalAlignment="Center" Margin="12,0">
<TextBlock Text="Oops!" Style="{ThemeResource HeaderTextBlockStyle}"/>
<TextBlock Text="{x:Bind ErrorText, Mode=OneWay}"/>
<Button Content="Continue" Style="{StaticResource ButtonStyle}" HorizontalAlignment="Center" Tapped="HideError"/>
</StackPanel>
</Grid>
</Controls:ModalDialog.ModalContent>
</Controls:ModalDialog>
然后当您点击 Continue
按钮时,模态框应该会消失。
这是一个基本的对话框实现。
<Controls:ModalDialog x:Name="ModalContainer"
CanBackButtonDismiss="False"
DisableBackButtonWhenModal="True"
IsModal="False"
ModalBackground="Blue">
<!-- content -->
<Controls:ModalDialog.Content>
<Controls:HamburgerMenu />
</Controls:ModalDialog.Content>
<!-- modal content -->
<Controls:ModalDialog.ModalContent>
<views:Busy x:Name="BusyView" />
</Controls:ModalDialog.ModalContent>
<!-- optional transition -->
<Controls:ModalDialog.ModalTransitions>
<ContentThemeTransition />
</Controls:ModalDialog.ModalTransitions>
</Controls:ModalDialog>
您可以随心所欲地实施,但这是我的做法。
public static void SetBusy(bool busy, string text = null)
{
WindowWrapper.Current().Dispatcher.Dispatch(() =>
{
Instance.BusyView.BusyText = text;
Instance.ModalContainer.IsModal = Instance.BusyView.IsBusy = busy;
});
}
Dispatcher 很重要,因为它是静态的,可以从任何线程调用。请注意,我自定义了 Busy 视图的 busyText
和 isBusy
值 - 但这对您的方法来说是独一无二的。重要的部分是 Instance.ModalContainer.IsModal
设置为 true 和 false 的地方。这是唯一控制 ModalDialog
控件状态的东西。
希望我的完整示例能有所帮助。
祝你好运。
我想在 Shell 视图中使用模态中的按钮关闭模板 10 的模态。 Shell.xaml.cs 中的关闭函数被触发,IsModal 和 HasError 被切换为 false,但模态对话框保持活动状态。
我使用的代码:
LandingpageViewModel:
public override async void OnNavigatedTo(object parameter, NavigationMode mode, IDictionary<string, object> state)
{
var i = await getMuscleScores();
if(i == null)
ShowError();
}
public void ShowError()
{
Views.Shell.SetError(true);
}
Shell.xaml.cs:
public bool IsModal { get; set; } = false;
public bool HasError { get; set; } = false;
public string ErrorText { get; set; } = "Something went wrong...";
public static void SetError(bool error, string text = null)
{
WindowWrapper.Current().Dispatcher.Dispatch(() =>
{
if (error)
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Collapsed;
else
BootStrapper.Current.UpdateShellBackButton();
Instance.IsModal = error;
Instance.IsBusy = !error;
Instance.HasError = error;
Instance.ErrorText = text == null ? "Something went wrong..." : text;
Instance.PropertyChanged?.Invoke(Instance, new PropertyChangedEventArgs(nameof(IsModal)));
Instance.PropertyChanged?.Invoke(Instance, new PropertyChangedEventArgs(nameof(HasError)));
Instance.PropertyChanged?.Invoke(Instance, new PropertyChangedEventArgs(nameof(ErrorText)));
});
}
public void HideError(object sender, TappedRoutedEventArgs e)
{
SetError(false);
}
Shell.xaml:
<Controls:ModalDialog.ModalContent>
<Grid>
<Viewbox Height="32">
<StackPanel Orientation="Horizontal" Visibility="{x:Bind IsBusy, Mode=OneWay, Converter={StaticResource visibilityConv}}">
<ProgressRing Width="16" Height="16"
Margin="12,0" Foreground="White"
IsActive="{x:Bind IsBusy, Mode=OneWay}" />
<TextBlock VerticalAlignment="Center" Foreground="White" Text="{x:Bind BusyText, Mode=OneWay}" />
</StackPanel>
</Viewbox>
<StackPanel Visibility="{x:Bind HasError, Mode=OneWay, Converter={StaticResource visibilityConv}}" VerticalAlignment="Center" Margin="12,0">
<TextBlock Text="Oops!" Style="{ThemeResource HeaderTextBlockStyle}"/>
<TextBlock Text="{x:Bind ErrorText, Mode=OneWay}"/>
<Button Content="Continue" Style="{StaticResource ButtonStyle}" HorizontalAlignment="Center" Tapped="HideError"/>
</StackPanel>
</Grid>
</Controls:ModalDialog.ModalContent>
我试图找到问题的另一件事是 LandingPageViewModel:
ShowError();
await Task.Delay(5000);
HideError();
这给我的结果与模式对话框保持打开状态相同。所以我认为使用不同的线程似乎出了问题。有人知道这个问题的解决方案吗?顺便说一句:我使用的是最新版本的模板 10 在此处输入代码
要关闭Template 10 的模态,我们需要将ModalDialog.IsModal
属性 设置为"false"。由于您的 XAML 代码不完整,我猜您使用的是 Template 10 Minimal 模板。在模板中它使用 IsBusy
设置 ModalDialog.IsModal
属性。但似乎您在代码隐藏中使用 IsModal
来控制 ModalDialog
,因此您可以将此 属性 绑定到 ModalDialog.IsModal
,如下所示:
<Controls:ModalDialog IsModal="{x:Bind IsModal, Mode=OneWay}">
<Controls:ModalDialog.Content>
...
</Controls:ModalDialog.Content>
<Controls:ModalDialog.ModalContent>
<Grid>
<Viewbox Height="32">
<StackPanel Orientation="Horizontal" Visibility="{x:Bind IsBusy, Mode=OneWay, Converter={StaticResource visibilityConv}}">
<ProgressRing Width="16" Height="16"
Margin="12,0" Foreground="White"
IsActive="{x:Bind IsBusy, Mode=OneWay}" />
<TextBlock VerticalAlignment="Center" Foreground="White" Text="{x:Bind BusyText, Mode=OneWay}" />
</StackPanel>
</Viewbox>
<StackPanel Visibility="{x:Bind HasError, Mode=OneWay, Converter={StaticResource visibilityConv}}" VerticalAlignment="Center" Margin="12,0">
<TextBlock Text="Oops!" Style="{ThemeResource HeaderTextBlockStyle}"/>
<TextBlock Text="{x:Bind ErrorText, Mode=OneWay}"/>
<Button Content="Continue" Style="{StaticResource ButtonStyle}" HorizontalAlignment="Center" Tapped="HideError"/>
</StackPanel>
</Grid>
</Controls:ModalDialog.ModalContent>
</Controls:ModalDialog>
然后当您点击 Continue
按钮时,模态框应该会消失。
这是一个基本的对话框实现。
<Controls:ModalDialog x:Name="ModalContainer"
CanBackButtonDismiss="False"
DisableBackButtonWhenModal="True"
IsModal="False"
ModalBackground="Blue">
<!-- content -->
<Controls:ModalDialog.Content>
<Controls:HamburgerMenu />
</Controls:ModalDialog.Content>
<!-- modal content -->
<Controls:ModalDialog.ModalContent>
<views:Busy x:Name="BusyView" />
</Controls:ModalDialog.ModalContent>
<!-- optional transition -->
<Controls:ModalDialog.ModalTransitions>
<ContentThemeTransition />
</Controls:ModalDialog.ModalTransitions>
</Controls:ModalDialog>
您可以随心所欲地实施,但这是我的做法。
public static void SetBusy(bool busy, string text = null)
{
WindowWrapper.Current().Dispatcher.Dispatch(() =>
{
Instance.BusyView.BusyText = text;
Instance.ModalContainer.IsModal = Instance.BusyView.IsBusy = busy;
});
}
Dispatcher 很重要,因为它是静态的,可以从任何线程调用。请注意,我自定义了 Busy 视图的 busyText
和 isBusy
值 - 但这对您的方法来说是独一无二的。重要的部分是 Instance.ModalContainer.IsModal
设置为 true 和 false 的地方。这是唯一控制 ModalDialog
控件状态的东西。
希望我的完整示例能有所帮助。
祝你好运。