【问题描述】
上位机和设备连接,有如下界面:
在打开该页面时,会去设备中读取设备的当前值,然后显示到界面上,目前设备中传感器的类型是0~20Bar。问题是显示后上位机又会把该值写到设备中,造成重复。
造成问题的代码:
<TextBlock Text="压力传感器设置" FontSize="16" VerticalAlignment="Center" Margin="15,8,0,8" FontWeight="Heavy" />
<RadioButton GroupName="PressureSensorType" Content="0~5Bar" IsChecked="{Binding PressureTypeList[0]}" Grid.Row="1" Grid.Column="1" VerticalAlignment="Center">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding SwitchPressureSensorTypeCommand}" CommandParameter="1"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</RadioButton>
<RadioButton GroupName="PressureSensorType" Content="0~10Bar" IsChecked="{Binding PressureTypeList[1]}" Grid.Row="1" Grid.Column="2" HorizontalAlignment="Left" VerticalAlignment="Center">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding SwitchPressureSensorTypeCommand}" CommandParameter="2"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</RadioButton>
<RadioButton GroupName="PressureSensorType" Content="0~20Bar" IsChecked="{Binding PressureTypeList[2]}" Grid.Row="1" Grid.Column="3" HorizontalAlignment="Left" VerticalAlignment="Center">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding SwitchPressureSensorTypeCommand}" CommandParameter="3"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</RadioButton>
【原因】
Checked 事件触发是基于IsChecked变量,一旦发生变化就会触发Checked事件,由于默认值都是false,所以一旦选中变成true就会触发。
上面代码还有一点不好的是这三个RadioButton绑定了3个不同的值,在ViewModel使用时要做很多的判断和联合,从逻辑上将应该是一个变量的三个不同的值。
修改后的代码:
View:
<TextBlock Text="压力传感器设置" FontSize="16" VerticalAlignment="Center" Margin="15,8,0,8" FontWeight="Heavy" />
<RadioButton GroupName="PressureSensorType" Content="0~5Bar" IsChecked="{Binding PressureType, Converter={StaticResource IntToBooleanConverter}, ConverterParameter=1}" Grid.Row="1" Grid.Column="1" VerticalAlignment="Center"/>
<RadioButton GroupName="PressureSensorType" Content="0~10Bar" IsChecked="{Binding PressureType, Converter={StaticResource IntToBooleanConverter}, ConverterParameter=2}" Grid.Row="1" Grid.Column="2" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<RadioButton GroupName="PressureSensorType" Content="0~20Bar" IsChecked="{Binding PressureType, Converter={StaticResource IntToBooleanConverter}, ConverterParameter=3}" Grid.Row="1" Grid.Column="3" HorizontalAlignment="Left" VerticalAlignment="Center"/>
ViewModel:
private UInt32 pressureType = 0;
public UInt32 PressureType
{
get
{
return pressureType;
}
set
{
if(pressureType != value)
{
pressureType = value;
RaisePropertyChanged("PressureType");
ReadWriteUInt32ArrayPackage readPressureSensorType = new ReadWriteUInt32ArrayPackage(Command.WRITE_PRESSURE_SENSOR_TYPE, this, new UInt32[] { pressureType }, 1, false);
SerialPortCommChannel.Instance.SendHighPriorityCommand(readPressureSensorType);
}
}
}
Converter:
public class IntToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
int data = int.Parse(value.ToString());
string name = parameter.ToString();
switch (name)
{
case "0":
return data == 0;
case "1":
return data == 1;
case "2":
return data == 2;
case "3":
return data == 3;
default:
return false;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
UInt32 val = 0;
if(uint.TryParse(parameter.ToString(),out val))
{
return val;
}
return 0;
}
}
【解决赋初值不回写的问题】
在第一个次赋初值的时候,赋值给成员变量pressureType,然后手动调用 RaisePropertyChanged("PressureType");来更新界面。