MAUI中WebView URL变化时如何调用OnAuthUrlChanged函数
解决WebView URL变化时ViewModel回调不触发的问题
问题根源:你绑定的是UrlWebViewSource对象,WebView导航时只会修改该对象的Url属性,不会替换整个AuthUrl对象。而[ObservableProperty]生成的回调仅在对象本身被替换时触发,因此OnAuthUrlChanged不会执行。
以下是三种可行的解决方法:
方法一:绑定字符串类型的URL(最简单)
直接将ViewModel中的属性改为string类型,WebView的Source属性可以自动将字符串转换为WebViewSource,双向绑定会在URL变化时更新字符串属性,触发回调。
修改ViewModel:
public partial class LoginViewModel : ObservableObject { private readonly IConfiguration configuration; public LoginViewModel(IConfiguration config) { configuration = config; AuthUrl = configuration.GetSection("Connections").GetValue<string>("LoginUrl"); } [ObservableProperty] private string? authUrl; // URL变化时会触发这个回调 partial void OnAuthUrlChanged(string? value) { Console.WriteLine($"当前URL变为:{value}"); } }
修改XAML:
<ContentPage.Content> <WebView Source="{Binding AuthUrl, Mode=TwoWay}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"/> </ContentPage.Content>
方法二:监听WebView的导航事件
通过WebView的Navigated或Navigating事件,在页面后台或使用行为通知ViewModel处理URL变化。
示例:页面后台处理
<ContentPage.Content> <WebView Source="{Binding AuthUrl}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Navigated="WebView_Navigated"/> </ContentPage.Content>
页面后台代码:
private void WebView_Navigated(object sender, WebNavigatedEventArgs e) { if (BindingContext is LoginViewModel vm) { vm.HandleUrlChanged(e.Url); } }
ViewModel中添加处理方法:
public void HandleUrlChanged(string url) { Console.WriteLine($"当前URL变为:{url}"); // 这里可以做你需要的逻辑处理 }
方法三:自定义可观察的UrlWebViewSource
创建一个继承自UrlWebViewSource的类,让Url属性触发PropertyChanged事件,然后在ViewModel中监听该属性变化。
自定义可观察类:
public class ObservableUrlWebViewSource : UrlWebViewSource, INotifyPropertyChanged { private string? _url; public new string? Url { get => _url; set { if (_url != value) { _url = value; OnPropertyChanged(nameof(Url)); } } } public event PropertyChangedEventHandler? PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
修改ViewModel:
public partial class LoginViewModel : ObservableObject { private readonly IConfiguration configuration; private ObservableUrlWebViewSource? _authUrl; public LoginViewModel(IConfiguration config) { configuration = config; AuthUrl = new ObservableUrlWebViewSource { Url = configuration.GetSection("Connections").GetValue<string>("LoginUrl") }; AuthUrl.PropertyChanged += AuthUrl_PropertyChanged; } public ObservableUrlWebViewSource? AuthUrl { get => _authUrl; set => SetProperty(ref _authUrl, value); } private void AuthUrl_PropertyChanged(object? sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(ObservableUrlWebViewSource.Url)) { Console.WriteLine($"当前URL变为:{((ObservableUrlWebViewSource)sender!).Url}"); // 执行你的逻辑 } } }
修改XAML:
<ContentPage.Content> <WebView Source="{Binding AuthUrl, Mode=TwoWay}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"/> </ContentPage.Content>
内容的提问来源于stack exchange,提问作者Timotej Arnuš
相关产品推荐
相关产品推荐

