具有 Label-Entry 个重复的 Xamarin 表单的自定义内容视图
Custom content view with Label-Entry duplicates Xamarin forms
我有自定义内容视图,其中 Label
作为标题,另一个 Label
作为详细信息,编辑 Icon
;当单击图标时,详细信息标签将转换为 Entry
以进行更改,并且更改会转移到绑定。
我已将这些自定义视图中的多个绑定到相同 object 的不同属性并尝试编辑每个视图并移动到下一个,问题是它似乎重复了各个视图
我也放了 x:Name
但它仍然复制相同的值到上面的视图..
只是姓氏的编辑
现在,如果我移至第 3 个视图并对其进行编辑,它会将新值复制到所有之前编辑过的值。 - 在这种情况下,对于姓氏,考虑到它在页面中使用的视图不同,并且在调试时它只点击一次该方法,这很奇怪。
自定义内容视图:
<StackLayout Orientation="Horizontal"
VerticalOptions="Start"
Padding="25,10,25,10">
<StackLayout x:Name="stackLayoutDetail"
HorizontalOptions="FillAndExpand">
<Label x:Name="title"
Text="{Binding Title}" />
<Label x:Name="detail"
Text="{Binding Detail}"
FontSize="Large"
FontAttributes="Bold" />
</StackLayout>
<Image x:Name="editIcon"
Source="edit_icon.png"
WidthRequest="25"
HeightRequest="25"
IsVisible="{Binding EditIconVisible}">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="EditIcon_Clicked" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
后面的代码:
private static Entry newEntry = new Entry();
public static readonly BindableProperty DetailProperty = BindableProperty.Create(propertyName: nameof(Detail),
returnType: typeof(string),
declaringType: typeof(LabelledEntrywithIcon),
defaultValue: default(string));
public string Detail
{
get
{
return (string)GetValue(DetailProperty);
}
set => SetValue(DetailProperty, value);
}
private void EditIcon_Clicked(object sender, System.EventArgs e)
{
detailLabel = (Label)stackLayoutDetail.Children[1];
stackLayoutDetail.Children.RemoveAt(1);
newEntry.Text = Detail;
stackLayoutDetail.Children.Add(newEntry);
editIcon.IsVisible = false;
newEntry.Completed += NewEntry_Completed;
}
private void NewEntry_Completed(object sender, System.EventArgs e)
{
try
{
var _newText = newEntry.Text;
detailLabel.Text = _newText;
stackLayoutDetail.Children.RemoveAt(1);
stackLayoutDetail.Children.Add(detailLabel);
Detail = _newText;
editIcon.IsVisible = true;
}
catch (System.Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
页数
<local:LabelledEntrywithIcon x:Name="firstName"
Title="First Name"
Detail="{Binding Fella.FirstName}" />
<local:LabelledEntrywithIcon x:Name="lastname"
Title="Last Name"
Detail="{Binding Fella.LastName}" />
<local:LabelledEntrywithIcon x:Name="gender"
Title="Gender"
Detail="{Binding Fella.Gender}" />
后面的代码:
ViewModel=new MainViewModel();
BindingContext = ViewModel;
要测试的完整代码位于 Github 回购:https://github.com/pmahend1/CustomViewDuplicationIssue
奇怪,但我更改了一行代码,现在可以按预期工作了。
在 class 变量上 private static Entry newEntry= new Entry();
更改为
private static Entry newEntry;
在EditIcon_Clicked
方法中而不是newEntry.Text = Detail;
使用
newEntry = new Entry { Text = Detail };
我不确定为什么它采用相同的引用,即使每个 LabelledEntrywithIcon
都有新条目
您可以通过以下方式简化问题,而不是创建新条目并查找和删除标签并添加新条目:
<StackLayout Orientation="Horizontal"
VerticalOptions="Start"
Padding="25,10,25,10">
<StackLayout x:Name="stackLayoutDetail"
HorizontalOptions="FillAndExpand">
<Label x:Name="title"
Text="{Binding Title}" />
<Label x:Name="detail"
Text="{Binding Detail}"
IsVisible="{Binding ShowLabel}"
FontSize="Large"
FontAttributes="Bold" />
<Entry ... IsVisible="{Binding ShowEntry}" ... />
</StackLayout>
<Image x:Name="editIcon"
Source="edit_icon.png"
WidthRequest="25"
HeightRequest="25"
IsVisible="{Binding ShowLabel}">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="EditIcon_Clicked" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
请注意,我有意在条目元素内写了 ... 作为占位符,用于您可能希望在此处执行的所有自定义设置(字体大小等)。
现在您添加两个 BindablyProperties(类型 bool)ShowEntry 和 ShowLabel,其中 ShowLabel 默认为 true,ShowEntry 默认为 false。
现在您所要做的就是调整您的 EditIcon_Clicked 事件:
private void EditIcon_Clicked(object sender, System.EventArgs e)
{
ShowLabel = false;
ShowEntry = true;
newEntry.Text = Detail;
newEntry.Completed += NewEntry_Completed;
}
并使NewEntry_Completed适应
private void NewEntry_Completed(object sender, System.EventArgs e)
{
try
{
var _newText = newEntry.Text;
detailLabel.Text = _newText;
ShowLabel = true;
ShowEntry = false;
Detail = _newText;
}
catch (System.Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
基本上这与您的解决方案相同,但是您不必在代码隐藏中推送 UI 项目,尤其是随之而来的错误和错误。
我有自定义内容视图,其中 Label
作为标题,另一个 Label
作为详细信息,编辑 Icon
;当单击图标时,详细信息标签将转换为 Entry
以进行更改,并且更改会转移到绑定。
我已将这些自定义视图中的多个绑定到相同 object 的不同属性并尝试编辑每个视图并移动到下一个,问题是它似乎重复了各个视图
我也放了 x:Name
但它仍然复制相同的值到上面的视图..
只是姓氏的编辑
现在,如果我移至第 3 个视图并对其进行编辑,它会将新值复制到所有之前编辑过的值。 - 在这种情况下,对于姓氏,考虑到它在页面中使用的视图不同,并且在调试时它只点击一次该方法,这很奇怪。
自定义内容视图:
<StackLayout Orientation="Horizontal"
VerticalOptions="Start"
Padding="25,10,25,10">
<StackLayout x:Name="stackLayoutDetail"
HorizontalOptions="FillAndExpand">
<Label x:Name="title"
Text="{Binding Title}" />
<Label x:Name="detail"
Text="{Binding Detail}"
FontSize="Large"
FontAttributes="Bold" />
</StackLayout>
<Image x:Name="editIcon"
Source="edit_icon.png"
WidthRequest="25"
HeightRequest="25"
IsVisible="{Binding EditIconVisible}">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="EditIcon_Clicked" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
后面的代码:
private static Entry newEntry = new Entry();
public static readonly BindableProperty DetailProperty = BindableProperty.Create(propertyName: nameof(Detail),
returnType: typeof(string),
declaringType: typeof(LabelledEntrywithIcon),
defaultValue: default(string));
public string Detail
{
get
{
return (string)GetValue(DetailProperty);
}
set => SetValue(DetailProperty, value);
}
private void EditIcon_Clicked(object sender, System.EventArgs e)
{
detailLabel = (Label)stackLayoutDetail.Children[1];
stackLayoutDetail.Children.RemoveAt(1);
newEntry.Text = Detail;
stackLayoutDetail.Children.Add(newEntry);
editIcon.IsVisible = false;
newEntry.Completed += NewEntry_Completed;
}
private void NewEntry_Completed(object sender, System.EventArgs e)
{
try
{
var _newText = newEntry.Text;
detailLabel.Text = _newText;
stackLayoutDetail.Children.RemoveAt(1);
stackLayoutDetail.Children.Add(detailLabel);
Detail = _newText;
editIcon.IsVisible = true;
}
catch (System.Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
页数
<local:LabelledEntrywithIcon x:Name="firstName"
Title="First Name"
Detail="{Binding Fella.FirstName}" />
<local:LabelledEntrywithIcon x:Name="lastname"
Title="Last Name"
Detail="{Binding Fella.LastName}" />
<local:LabelledEntrywithIcon x:Name="gender"
Title="Gender"
Detail="{Binding Fella.Gender}" />
后面的代码:
ViewModel=new MainViewModel();
BindingContext = ViewModel;
要测试的完整代码位于 Github 回购:https://github.com/pmahend1/CustomViewDuplicationIssue
奇怪,但我更改了一行代码,现在可以按预期工作了。
在 class 变量上 private static Entry newEntry= new Entry();
更改为
private static Entry newEntry;
在EditIcon_Clicked
方法中而不是newEntry.Text = Detail;
使用
newEntry = new Entry { Text = Detail };
我不确定为什么它采用相同的引用,即使每个 LabelledEntrywithIcon
您可以通过以下方式简化问题,而不是创建新条目并查找和删除标签并添加新条目:
<StackLayout Orientation="Horizontal"
VerticalOptions="Start"
Padding="25,10,25,10">
<StackLayout x:Name="stackLayoutDetail"
HorizontalOptions="FillAndExpand">
<Label x:Name="title"
Text="{Binding Title}" />
<Label x:Name="detail"
Text="{Binding Detail}"
IsVisible="{Binding ShowLabel}"
FontSize="Large"
FontAttributes="Bold" />
<Entry ... IsVisible="{Binding ShowEntry}" ... />
</StackLayout>
<Image x:Name="editIcon"
Source="edit_icon.png"
WidthRequest="25"
HeightRequest="25"
IsVisible="{Binding ShowLabel}">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="EditIcon_Clicked" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
请注意,我有意在条目元素内写了 ... 作为占位符,用于您可能希望在此处执行的所有自定义设置(字体大小等)。
现在您添加两个 BindablyProperties(类型 bool)ShowEntry 和 ShowLabel,其中 ShowLabel 默认为 true,ShowEntry 默认为 false。 现在您所要做的就是调整您的 EditIcon_Clicked 事件:
private void EditIcon_Clicked(object sender, System.EventArgs e)
{
ShowLabel = false;
ShowEntry = true;
newEntry.Text = Detail;
newEntry.Completed += NewEntry_Completed;
}
并使NewEntry_Completed适应
private void NewEntry_Completed(object sender, System.EventArgs e)
{
try
{
var _newText = newEntry.Text;
detailLabel.Text = _newText;
ShowLabel = true;
ShowEntry = false;
Detail = _newText;
}
catch (System.Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
基本上这与您的解决方案相同,但是您不必在代码隐藏中推送 UI 项目,尤其是随之而来的错误和错误。