Xamarin Forms 中的多重绑定:元素为空
MultiBinding in Xamarin Forms: element is null
我正在尝试将 MultiBinding 与 Xamarin.Forms 4.8 一起使用,但我无法让它工作。我有这个非常简单的转换器:
public class QuantityLabelConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return "Hello World";
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
我正尝试在 XAML 标签中使用它,如下所示:
<Label>
<Label.Text>
<MultiBinding Converter="{StaticResource QuantityLabelConverter}">
<Binding Path="SelectedQuantity" />
<Binding Path="OutstandingQuantity" />
</MultiBinding>
</Label.Text>
</Label>
现在,当我调试时,我可以看到转换器被调用了三次:一次有两个空值,另一次是在设置 SelectedQuantity 值时,最后一次是在分配 OutstandingQuantity 值时。所以绑定和转换器之间的 link 似乎工作正常。
但是,页面崩溃了,我收到“值不能为空。\n参数名称:元素”System.ArgumentNullException。
如果我用简单的
替换之前的XAML
<Label Text="Hello World">
页面显示没有问题,所以MultiBinding的设置有问题,但我不知道是什么...
您需要 return BindableProperty.UnsetValue 才能使用绑定 FallbackValue 。
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
foreach (var value in values)
{
if (!(value is string b))
{
return "xxx";
// set a default value when unset
}
}
string str1 = values[0].ToString();
string str2 = values[1].ToString();
return str1+str2;
}
##更新
我已经测试了样本并找出了原因
如果你想绑定 ViewModel 的属性。您需要实现 属性 的接口 INotifyPropertyChanged 而不是 BindableObject 。
public class MainViewModel : INotifyPropertyChanged
{
string _name="";
string _surname="";
public string Name
{
get { return _name; }
set
{
if(_name!=value)
{
_name = value;
OnPropertyChanged("Name");
}
}
}
public string Surname
{
get { return _surname; }
set
{
if(_surname!=value)
{
_surname = value;
OnPropertyChanged("Surname");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class NameConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
foreach (var value in values)
{
if (!(value is string b))
{
return " ";
// set a default value when unset
}
}
string str1 = values[0].ToString();
string str2 = values[1].ToString();
return str1 + str2;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
我正在尝试将 MultiBinding 与 Xamarin.Forms 4.8 一起使用,但我无法让它工作。我有这个非常简单的转换器:
public class QuantityLabelConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return "Hello World";
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
我正尝试在 XAML 标签中使用它,如下所示:
<Label>
<Label.Text>
<MultiBinding Converter="{StaticResource QuantityLabelConverter}">
<Binding Path="SelectedQuantity" />
<Binding Path="OutstandingQuantity" />
</MultiBinding>
</Label.Text>
</Label>
现在,当我调试时,我可以看到转换器被调用了三次:一次有两个空值,另一次是在设置 SelectedQuantity 值时,最后一次是在分配 OutstandingQuantity 值时。所以绑定和转换器之间的 link 似乎工作正常。
但是,页面崩溃了,我收到“值不能为空。\n参数名称:元素”System.ArgumentNullException。
如果我用简单的
替换之前的XAML<Label Text="Hello World">
页面显示没有问题,所以MultiBinding的设置有问题,但我不知道是什么...
您需要 return BindableProperty.UnsetValue 才能使用绑定 FallbackValue 。
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
foreach (var value in values)
{
if (!(value is string b))
{
return "xxx";
// set a default value when unset
}
}
string str1 = values[0].ToString();
string str2 = values[1].ToString();
return str1+str2;
}
##更新
我已经测试了样本并找出了原因
如果你想绑定 ViewModel 的属性。您需要实现 属性 的接口 INotifyPropertyChanged 而不是 BindableObject 。
public class MainViewModel : INotifyPropertyChanged
{
string _name="";
string _surname="";
public string Name
{
get { return _name; }
set
{
if(_name!=value)
{
_name = value;
OnPropertyChanged("Name");
}
}
}
public string Surname
{
get { return _surname; }
set
{
if(_surname!=value)
{
_surname = value;
OnPropertyChanged("Surname");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class NameConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
foreach (var value in values)
{
if (!(value is string b))
{
return " ";
// set a default value when unset
}
}
string str1 = values[0].ToString();
string str2 = values[1].ToString();
return str1 + str2;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}