gpt4 book ai didi

c# - 支持基本类型和可空类型的两种方式可绑定(bind)条目

转载 作者:行者123 更新时间:2023-11-30 12:40:55 25 4
gpt4 key购买 nike

我正尝试在 Xamarin.Forms 中使用 Entry 实现完美的 MVVM。

我的模型包含类型包括 string、int?、decimal?、bool? 等的属性。每当我绑定(bind)到字符串类型时,两种绑定(bind)方式都会起作用,因为文本属性具有字符串类型(它们匹配)。但是一旦您尝试绑定(bind)回模型并且属性是 int 或 int?,它就不会更新模型的属性值。

在我的研究过程中,在 Xamarin 支持的帮助下,这是一个关于如何处理可空类型的非常有用的线程:

Nullable type in x:TypeArguments

XAML 代码:

<controls:NullableIntEntry Grid.Column="1" Grid.Row="14" NumericText="{Binding BusinessOwnership, Mode=TwoWay}" x:Name="lblBusinessOwnership"></controls:NullableIntEntry>

BindableEntry(入口扩展)代码:

using System;
using System.Collections;
using System.Collections.Specialized;
using System.Reflection;
using Xamarin.Forms;

namespace CreditBuilderApp.Controls
{
public class BindableEntry<T> : Entry
{
static bool firstLoad;

public static readonly BindableProperty NumericTextProperty =
BindableProperty.Create("NumericText", typeof(T), typeof(BindableEntry<T>),
null, BindingMode.TwoWay, propertyChanged: OnNumericTextChanged);

static void OnNumericTextChanged(BindableObject bindable, object oldValue, object newValue)
{
var boundEntry = (BindableEntry<T>)bindable;
if (firstLoad && newValue != null)
{
firstLoad = false;
boundEntry.Text = newValue.ToString();
}
}

public T NumericText
{
get { return (T)GetValue(NumericTextProperty); }
set { SetValue(NumericTextProperty, value); }
}

public BindableEntry()
{
firstLoad = true;
this.TextChanged += BindableEntry_TextChanged;
}

private void BindableEntry_TextChanged(object sender, TextChangedEventArgs e)
{
if (!String.IsNullOrEmpty(e.NewTextValue))
{
this.NumericText = (T)Convert.ChangeType(e.NewTextValue, typeof(T));
}
else
{
this.NumericText = default(T);
}
}
}
}

NullableIntEntry 和 NullableDecimalEntry(指定类型的可绑定(bind)条目扩展):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CreditBuilderApp.Controls
{
public class NullableIntEntry : BindableEntry<Int32?>
{

}

public class NullableDecimalEntry : BindableEntry<Decimal?>
{

}
}

型号:

      private int? _businessOwnership { get; set; }
public int? BusinessOwnership
{
get { return _businessOwnership; }
set
{
if (_businessOwnership != value)
{
_businessOwnership = value;
RaisePropertyChanged();
}
}
}

我实际上能够绑定(bind)到整数、小数、 float ,基本上是任何不是字符串的类型,这是朝着正确方向迈出的一步。但是,要完成此操作,我必须在上面创建 BindableEntry 并指定它是哪种类型。 (将 T 替换为 int?,将 T 替换为小数?等等。同时指定如何转换 e.NewTextValue。

问题:下面的类型更改转换破坏了双向绑定(bind)。

this.NumericText = (T)Convert.ChangeType(e.NewTextValue, typeof(T));

但是,这给了我一个错误(很明显),因为 this.NumericText 在运行时之前是 T 类型。

因此,如果我希望该条目适用于可为空的整数,我需要将所有类型 T 替换为 int 吗?以及将上面的代码更改为:

Convert.ToInt32(e.NewTextValue)

当我单步执行代码时,每当我到达 Convert.ChangeType 到 T 行时,它就会退出框架。没有错误并且显示了页面,但是特定可绑定(bind)条目之后的每个控件都没有值。

After stepping through the ConvertType function

如果我遗漏了任何信息,请告诉我。帮助将不胜感激!

最佳答案

我建议使用值转换器,它比创建自定义控件要容易得多,并且符合 MVVM 模式。

您可以在此处找到代码片段 - https://forums.xamarin.com/discussion/comment/60076/#Comment_60076

关于c# - 支持基本类型和可空类型的两种方式可绑定(bind)条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40142786/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com