嗨,我正在為 windows 的 MAUI 開發簡單的測驗應用程式。
問題是呼叫 PropertyChanged 時視圖頁面中的標簽不會改變。
而且我發現當我更改 [PortErrorMsg] 屬性時,我可以看到呼叫了 PropertyChanged 函式但是
未呼叫 [PortErrorMsg] 屬性中的“get”。
(Debug.WriteLine("檢查 get 是否正常作業的訊息"); <-- 不呼叫。)
這是我下面的代碼
xml:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:NxJig.ViewModels"
x:DataType="vm:JigViewModel"
x:Class="NxJig.Views.JigPage"
Title="JigPage">
<ContentPage.BindingContext>
<vm:JigViewModel/>
</ContentPage.BindingContext>
<VerticalStackLayout>
<HorizontalStackLayout Margin="30">
<Picker Title="Select Port" x:Name="picker1" SelectedIndexChanged="picker1_SelectedIndexChanged" FontSize="Large">
<Picker.Items>
<x:String>COM1</x:String>
<x:String>COM2</x:String>
<x:String>COM3</x:String>
<x:String>COM4</x:String>
<x:String>COM5</x:String>
<x:String>COM6</x:String>
<x:String>COM7</x:String>
<x:String>COM8</x:String>
<x:String>COM9</x:String>
<x:String>COM10</x:String>
<x:String>COM11</x:String>
<x:String>COM12</x:String>
<x:String>COM13</x:String>
<x:String>COM14</x:String>
<x:String>COM15</x:String>
<x:String>COM16</x:String>
<x:String>COM17</x:String>
<x:String>COM18</x:String>
<x:String>COM19</x:String>
<x:String>COM20</x:String>
</Picker.Items>
</Picker>
</HorizontalStackLayout>
<Label Text="{Binding PortErrorMsg, Mode=TwoWay}" IsEnabled="True" FontSize="Large"/>
</VerticalStackLayout>
</ContentPage>
Xaml 背后的代碼:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private void picker1_SelectedIndexChanged(object sender, EventArgs e)
{
ViewModel vm = new ViewModel();
vm.SerialPortName = picker1.SelectedItem as string;
}
}
視圖模型:
namespace NxJig.ViewModels
{
public class JigViewModel : INotifyPropertyChanged
{
private SerialPort serialPort;
private string serialPortName = "";
private string defaultStr = "init text";
private string successStr = "complete";
private string failStr = "check the port again";
public string portErrorMsg = defaultStr;
public event PropertyChangedEventHandler PropertyChanged;
public JigViewModel()
{
serialPort = new SerialPort();
serialPort.BaudRate = 9600;
serialPort.Parity = Parity.None;
serialPort.StopBits = StopBits.One;
serialPort.DataBits = 8;
}
public string SerialPortName
{
get => serialPortName;
set
{
if (serialPortName != value)
{
serialPortName = value;
Debug.WriteLine($"{serialPortName} is selected.");
OnPropertyChanged(nameof(SerialPortName));
serialPort.PortName = value;
if (!serialPort.IsOpen)
{
try
{
serialPort.Open();
if(serialPort.IsOpen)
{
this.PortErrorMsg = successStr;
}
}
catch
{
this.PortErrorMsg = failStr;
}
}
}
}
}
public string PortErrorMsg
{
set
{
if (portErrorMsg != value)
{
portErrorMsg = value;
Debug.WriteLine($"{portErrorMsg} is selected.");
OnPropertyChanged(nameof(PortErrorMsg));
}
}
get
{
Debug.WriteLine("Message for checking whether get is working properly");
return portErrorMsg;
}
}
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
Debug.WriteLine($"propertyName is {propertyName}");
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
else
{
Debug.WriteLine("PropertyChanged is null !");
}
}
}
}
我希望在呼叫 PropertyChanged 時更改 xaml 中的標簽。
uj5u.com熱心網友回復:
從我的角度來看,創建了兩個ViewModel。一個是在您的xaml中創建的:
<ContentPage.BindingContext>
<vm:JigViewModel/>
</ContentPage.BindingContext>
在您的活動中創建另一個:
private void picker1_SelectedIndexChanged(object sender, EventArgs e)
{
ViewModel vm = new ViewModel(); // i supposed it's JigViewModel, right?
vm.SerialPortName = picker1.SelectedItem as string;
}
您在 xaml 中的視圖系結到第一個視圖。當您觸發 picker1_SelectedIndexChanged 時,它只會創建一個與您的視圖無關的新 ViewModel。因此,PropertyChanged 屬性始終為 null,并且您的標簽無法更改。
這里我給你一些建議。在您的代碼系結 .CS
public partial class MainPage : ContentPage
{
JigViewModel vm;
public MainPage()
{
InitializeComponent();
vm = new JigViewModel();
this.BindingContext = vm;
}
private void picker1_SelectedIndexChanged(object sender, EventArgs e)
{
vm.SerialPortName = picker1.SelectedItem as string;
}
在您的 xaml 中,洗掉以下代碼:
<ContentPage.BindingContext>
<vm:JigViewModel/>
</ContentPage.BindingContext>
希望我的回答能幫到你。
uj5u.com熱心網友回復:
如果我在你的位置,我會:
- 使用 CommunityToolkit.MVVM。
- 使用注解將 Picker 的 SelectedItem 系結到 ObservableProperty。
- 如果需要,請在部分 void OnSerialPortChanged(...) 中撰寫一些代碼。
你不需要那些事件。您不需要手動呼叫方法。您不必撰寫任何樣板代碼。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/522092.html
上一篇:帶有連接節點的鏈接的聚集氣泡
