[英]UWP Two Radio Buttons using two-way binding stop working after page navigation
我有兩個單選按鈕,它們使用雙向綁定到兩個布爾屬性,即視圖模型的X
和Y
由於單選按鈕是互斥的,因此設置X
自動清除Y
,反之亦然。 現在,如果我導航到其他頁面,請返回,再次導航到該頁面,然后使用單選按鈕返回頁面,這些按鈕將停止工作。
重現此問題的步驟:
在App.xaml.cs中,在行sealed partial class App : Application
之前添加以下代碼sealed partial class App : Application
(請包含System.ComponentModel
和System.Runtime.CompilerServices
命名空間)
public class ViewModel : INotifyPropertyChanged { private bool _X; public bool X { get => _X; set { if (value != _X) { _X = value; OnPropertyChanged(); } } } private bool _Y; public bool Y { get => _Y; set { if (value != _Y) { _Y = value; OnPropertyChanged(); } } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
並在App
類中,添加
public static ViewModel VM = new ViewModel();
在MainPage.xaml中,將頁面內容替換為
<StackPanel> <RadioButton IsChecked="{x:Bind VM.X, Mode=TwoWay}" Content="X"/> <RadioButton IsChecked="{x:Bind VM.Y, Mode=TwoWay}" Content="Y"/> <Button Content="Navigate" Click="Button_Click"/> </StackPanel>
並在MainPage.xaml.cs中,將MainPage
類替換為
public sealed partial class MainPage : Page { public ViewModel VM => App.VM; public MainPage() { InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { Frame.Navigate(typeof(BlankPage1)); } }
將空白頁添加到您的項目,並在其.xaml文件中,將其頁面內容替換為
<Grid> <Button Click="Button_Click" Content="Back"/> </Grid>
並在其.cs文件中添加以下按鈕處理程序
private void Button_Click(object sender, RoutedEventArgs e) { Frame.Navigate(typeof(MainPage)); }
編譯並啟動該應用程序,然后在運行該應用程序時,單擊單選按鈕以確認它們正在運行。
單擊導航,然后單擊上一步。 此時單選按鈕正在工作。
再次,單擊導航,然后單擊上一步。 這些按鈕不再起作用。
是什么導致按鈕停止工作? 這是錯誤還是我錯過了某些東西,並且行為正常? 謝謝。
嘗試向單選按鈕添加組名:
<StackPanel>
<RadioButton IsChecked="{x:Bind VM.X, Mode=TwoWay}" Content="X" GroupName="Group1"/>
<RadioButton IsChecked="{x:Bind VM.Y, Mode=TwoWay}" Content="Y" GroupName="Group1"/>
<Button Content="Navigate" Click="Button_Click"/>
</StackPanel>
有幫助嗎?
首先,最好在UI完全加載之前初始化Core ViewModel,這會使綁定更平滑。
為此,請在XAML上創建Datacontext對象。 在 - 的里面
<MainPage.DataContext> <yourviewmodelnamespace:YourViewModel/> </MainPage.DataContext> <Grid> etc....
引用您的dataconext在Page類中創建一個Get only屬性,例如
public YourViewModel mydatacontext{ get{ return DataContext as YourViewModel;} }
說完了,就簡化一下。
您只需要一個“屬性綁定”,並且由於只有兩個選項,因此應在彼此頂部使用兩個復選框,第一個復選框將綁定到屬性的常規值,而另一個復選框則相反。
請注意,復選框IsChecked實際上是可為空的布爾值(布爾值)。 如前所述,為了實現這一單一屬性系統,您將必須使用所謂的A Converter ,在我們的情況下,該轉換器將簡單地逆轉傳入的值,這看起來似乎很復雜,但是我向您保證,它是實現這一目標的最干凈,最有效的方法這樣的功能。
示例代碼:1. YourViewModel.cs
private bool? _y; public bool? IsYCheckboxChecked { get => _y; set { if (value != _y) { _Y = value; OnPropertyChanged(); } } }
namespace YourConvertNameSpace{ public Class NullBoolReverser{// this is the converter we are going to use to reverse the bool? public object Convert(object value, Type targetType, object parameter, string language) { var val = (bool?)value; return !val; } public object ConvertBack(object value, Type targetType, object parameter, string language) { var val = (bool?)value; return !val; } } }
<MainPage.Resources> <YourConvertNameSpace:NullBoolReverser x:Key="MyReverserKey"/> </MainPage.Resources> <MainPage.DataContext> <your datacontextgoes here, like i showed before, it will be accessed by a get only prop called 'mydatacontext'> </MainPage.DataContext> <Grid> <StackPanel <CheckBox Name="Ycheckbox" IsChecked="{x:Bind 'mydatacontext.IsYCheckboxChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> This is Y </CheckBox <CheckBox IsChecked="{x:Bind Ycheckbox.IsChecked, Converter={StaticResource MyReverserKey}, Mode=TwoWay}"> This is X </CheckBox><!--This Bind Allows a and exclusive clause between the two cheboxes thanks to the nullbool reverser--> </StackPanel </Grid </Page>
這都是從頭頂和腳底寫出來的,因此請原諒格式,編輯器太遲鈍和笨拙,即使將綁定表達式看成多行,也不要將其分解為不同的行。
Edit:build最好在每個步驟之后構建項目,因為xaml編輯器通常不會立即識別諸如普通類或轉換器之類的非ui frameork元素。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.