WPF繫結失效問題(規避解決)
阿新 • • 發佈:2019-01-31
使用WPF繫結後臺資料,在多次切換資料後繫結失效
將一個後臺資料繫結到多個RadioButton的IsChecked上,通過自定義轉換將整型資料轉換成bool型資料。點選介面上的新增按鈕,在button事件中,將繫結的物件資料加1,然後再前臺顯示,在多次後,前臺的RadioButton中會出現某個繫結失敗問題。
自定義轉換器程式碼:
#region 方法
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null)
{
try
{
if (parameter != null)
{
int par = 0;
if (int.TryParse(parameter.ToString(), out par))
{
return (value as int?).Value - par == 0;
}
return false;
}
else
return false;
}
catch (System.Exception)
{
return false;
}
}
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
try
{
if (parameter != null)
{
int par = 0;
if (int.TryParse(parameter.ToString(), out par))
{
if ((bool)value)
return par;
return null;
}
return 0;
}
else
{
return (bool)value ? 1 : 0;
}
}
catch (System.Exception)
{
}
return null;
}
#endregion
XAml程式碼:
<DockPanel x:Name="grid" LastChildFill="False">
<DockPanel.DataContext>
<local:Student/>
</DockPanel.DataContext>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" HorizontalAlignment="Center" >
<Button HorizontalAlignment="Center" Width ="60" Height="60" Click="Add_Click" Content="新增"/>
<Button HorizontalAlignment="Center" Width ="60" Height="60" Click="Delete_Click" Content="刪除"/>
</StackPanel>
<RadioButton x:Name="rbtn_4" Content="test4" DockPanel.Dock="Top" IsChecked="{Binding Age, ConverterParameter=1, Converter={StaticResource IntToBoolConverter}}" GroupName="test2" Margin="0,10,0,0"/>
<RadioButton x:Name="rbtn_5" Content="test5" DockPanel.Dock="Top" IsChecked="{Binding Age, ConverterParameter=2, Converter={StaticResource IntToBoolConverter}}" GroupName="test2"/>
<RadioButton x:Name="rbtn_6" Content="test6" DockPanel.Dock="Top" IsChecked="{Binding Age, ConverterParameter=3, Converter={StaticResource IntToBoolConverter}}" GroupName="test2"/>
<RadioButton x:Name="rbtn_7" Content="test7" DockPanel.Dock="Top" IsChecked="{Binding Age, ConverterParameter=4, Converter={StaticResource IntToBoolConverter}}" GroupName="test2"/>
<TextBox DockPanel.Dock="Top" Margin="0,10,0,0" Text="{Binding Age, ConverterParameter=1, Converter={StaticResource IntToBoolConverter}}"></TextBox>
<TextBox DockPanel.Dock="Top" Margin="0,10,0,0" Text="{Binding Age, ConverterParameter=2, Converter={StaticResource IntToBoolConverter}}"></TextBox>
<TextBox DockPanel.Dock="Top" Margin="0,10,0,0" Text="{Binding Age, ConverterParameter=3, Converter={StaticResource IntToBoolConverter}}"></TextBox>
<TextBox DockPanel.Dock="Top" Margin="0,10,0,0" Text="{Binding Age, ConverterParameter=4, Converter={StaticResource IntToBoolConverter}}"></TextBox>
</DockPanel>
前臺程式碼:
private void Add_Click(object sender, RoutedEventArgs e)
{
Student tstd = grid.DataContext as Student;
tstd.Age = tstd.Age % 4 + 1;
}
Student:
class Student : INotifyPropertyChanged
{
#region 屬性
string name;
public string Name
{
get { return name; }
set
{
name = value;
if (this.PropertyChanged != null)
{
this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Name"));
}
}
}
public String ID
{
set;
get;
}
int age = 1;
public int Age
{
set
{
if (value == -1)
return;
age = value;
if (this.PropertyChanged != null)
{
this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Age"));
}
}
get { return age; }
}
IP ip = new IP("127.0.0.1");
public IP IP
{
get { return ip; }
set
{
ip = value;
if (this.PropertyChanged != null)
{
this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("IP"));
}
}
}
#endregion
#region 方法
public Student Clone()
{
Student stu = new Student();
stu.Name = this.Name;
stu.Age = this.Age;
stu.ID = this.ID + 1;
return stu;
}
#endregion
#region 事件
#endregion
public event PropertyChangedEventHandler PropertyChanged;
}
目前的解決方案是使用CheckBox代替Radiobutton,同時針對CheckBox的Click方法額外處理(禁用Check的取消選中功能)。
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
(sender as CheckBox).IsChecked = true;
e.Handled = true;
}
多個CheckBox之間的單選性採用繫結到同一個變數來處理(使用到上面的自定義轉換器)。
猜測:
單選按鈕同一組內按鈕的是否選中是關聯的,在你選中其中某個項時,底層會將其他選項的IsChecked屬性進行更新,此時與繫結衝突照成繫結的失效,而CheckBox是否選中只針對自己。