Xamarin Forms 自定义控件仅在更改 ItemSelected 时通知模型
Xamarin Forms Custom Control only Notify Model on change ItemSelected
大家好,我在我的 Xamarin Forms 项目中遇到了一些问题,在我的应用程序中,ListView 在列中显示多行数据 (500++),Xamarin Forms ListView 渲染速度太慢(并且消耗 ram滚动),然后我创建了一个自定义控件来使用本机 ListView,这非常有帮助,现在渲染速度不是问题(滚动中的 ram consumo 也不是问题)。
但是使用这个方法有一个问题,现在当我编辑一个嵌入在列表视图行中的文本框时,模型上的 属性 没有被通知,只有当我改变 ItemSelected 时才会被通知.
//我的自定义控件
public class NativeListView : ListView
{
public NativeListView()
{
}
}
// 我的自定义控件渲染器
[assembly: ExportRenderer(typeof(NativeListView), typeof(NativeListViewRenderer))]
namespace AppName.UWP.NativeCode.CustomControlsRenderers
{
public class NativeListViewRenderer : ListViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
{
base.OnElementChanged(e);
if (Control is ListView listView)
{
listView.ItemTemplate = App.Current.Resources["NativeListViewItemTemplate"] as DataTemplate;
}
}
}
}
// 我的数据模板
<DataTemplate x:Key="NativeListViewItemTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0"
Text="{Binding Value, Mode=TwoWay}"/>
<TextBlock Grid.Column="1"
Foreground="Red"
Text="{Binding Validate}"/>
</Grid>
</DataTemplate>
// 我的页面 XAML
<customcontrols:NativeListView
Grid.Row="2"
VerticalOptions="FillAndExpand"
SelectionMode="Single"
ItemsSource="{Binding NativeListView_ItemsSource}"/>
// 我的 PageViewModel
public class Model : BindableBase
{
private string _value;
public string Value
{
get { return _value; }
set { SetProperty(ref _value, value, () => RaisePropertyChanged(nameof(Validate))); }
}
public string Validate
{
get
{
if (string.IsNullOrWhiteSpace(Value))
{
return "❌";
}
return "✔";
}
}
}
private ObservableCollection<Model> nativeListView_ItemsSource;
public ObservableCollection<Model> NativeListView_ItemsSource
{
get { return nativeListView_ItemsSource; }
set { SetProperty(ref nativeListView_ItemsSource, value); }
}
// 构造函数:
NativeListView_ItemsSource = new ObservableCollection<Model>
{
new Model(){Value="8"},new Model(){Value="1"},new Model(){Value=""},
new Model(){Value="6"},new Model(){Value=""},new Model(){Value="4"},
new Model(){Value="7"},new Model(){Value="5"},new Model(){Value="7"},
};
我肯定会对原始设置感兴趣,因为我认为 Xamarin.Forms DataTemplate
不会导致任何性能问题,尤其是在 UWP 上,所以请随时分享原始代码还有。
然而,在这种情况下,在 UWP 中,TextBox
中的 属性 更改通知仅在控件失去焦点后发生。如果你想让通知在每次击键后发生,你需要编辑 Binding
如下:
Text="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
大家好,我在我的 Xamarin Forms 项目中遇到了一些问题,在我的应用程序中,ListView 在列中显示多行数据 (500++),Xamarin Forms ListView 渲染速度太慢(并且消耗 ram滚动),然后我创建了一个自定义控件来使用本机 ListView,这非常有帮助,现在渲染速度不是问题(滚动中的 ram consumo 也不是问题)。
但是使用这个方法有一个问题,现在当我编辑一个嵌入在列表视图行中的文本框时,模型上的 属性 没有被通知,只有当我改变 ItemSelected 时才会被通知.
//我的自定义控件
public class NativeListView : ListView
{
public NativeListView()
{
}
}
// 我的自定义控件渲染器
[assembly: ExportRenderer(typeof(NativeListView), typeof(NativeListViewRenderer))]
namespace AppName.UWP.NativeCode.CustomControlsRenderers
{
public class NativeListViewRenderer : ListViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
{
base.OnElementChanged(e);
if (Control is ListView listView)
{
listView.ItemTemplate = App.Current.Resources["NativeListViewItemTemplate"] as DataTemplate;
}
}
}
}
// 我的数据模板
<DataTemplate x:Key="NativeListViewItemTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0"
Text="{Binding Value, Mode=TwoWay}"/>
<TextBlock Grid.Column="1"
Foreground="Red"
Text="{Binding Validate}"/>
</Grid>
</DataTemplate>
// 我的页面 XAML
<customcontrols:NativeListView
Grid.Row="2"
VerticalOptions="FillAndExpand"
SelectionMode="Single"
ItemsSource="{Binding NativeListView_ItemsSource}"/>
// 我的 PageViewModel
public class Model : BindableBase
{
private string _value;
public string Value
{
get { return _value; }
set { SetProperty(ref _value, value, () => RaisePropertyChanged(nameof(Validate))); }
}
public string Validate
{
get
{
if (string.IsNullOrWhiteSpace(Value))
{
return "❌";
}
return "✔";
}
}
}
private ObservableCollection<Model> nativeListView_ItemsSource;
public ObservableCollection<Model> NativeListView_ItemsSource
{
get { return nativeListView_ItemsSource; }
set { SetProperty(ref nativeListView_ItemsSource, value); }
}
// 构造函数:
NativeListView_ItemsSource = new ObservableCollection<Model>
{
new Model(){Value="8"},new Model(){Value="1"},new Model(){Value=""},
new Model(){Value="6"},new Model(){Value=""},new Model(){Value="4"},
new Model(){Value="7"},new Model(){Value="5"},new Model(){Value="7"},
};
我肯定会对原始设置感兴趣,因为我认为 Xamarin.Forms DataTemplate
不会导致任何性能问题,尤其是在 UWP 上,所以请随时分享原始代码还有。
然而,在这种情况下,在 UWP 中,TextBox
中的 属性 更改通知仅在控件失去焦点后发生。如果你想让通知在每次击键后发生,你需要编辑 Binding
如下:
Text="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"