在绑定到 ListView 之前从 ViewModel 修改 属性
Modify property from ViewModel before binding to ListView
我正在使用 Prism MVVM 将 ItemSource
绑定到 ListView
。这是列表 Cell
<ListView x:Name="list1" ItemsSource="{Binding StudentList}">
<ListView.ItemTemplate >
<DataTemplate>
<ViewCell>
<StackLayout>
<Label VerticalTextAlignment="Center"
Text="{Binding StudentName}" />
<Button x:Name="mybtn"
BindingContext="{Binding Source={x:Reference list1}, Path=BindingContext}"
Command="{Binding BtnTextCommand}"
CommandParameter="{Binding Source={x:Reference mybtn}}"
Text="{Binding BtnText}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
这是 ViewModel
中的来源
private List<Student> _studentList;
public List<Student> StudentList
{
get { return _studentList; }
set { SetProperty(ref _studentList, value); }
}
我想在绑定之前为每个列表项每次修改按钮 Text
。我怎样才能从 ViewModel
Class 获取 BtnText
的更新值?
修改值表示如果Text
有ID value
则显示'Present'如果为空则显示'Absent'等
学生Class
public class Student
{
public Mychildren MyKid { get; set; }
public string LocalStudentId { get; set; }
public int? StudentId { get; set; }
public string StudentName { get; set; }
public int? AttendanceTypeStatusId { get; set; }
public int? StudentDailyAttendanceId { get; set; }
public int? AbsentReasonId { get; set; }
public string AttendanceTypeStatusCD { get; set; }}
}
编辑:
我已经在 Converter 中编写了这个逻辑,在 value
的第一 else
部分抛出异常
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string attStatusId = string.Empty;
//AttendanceTypeStatusId
if (value != null)
{
attStatusId = "Present";
}
else
{
attStatusId = SISConst.AttendanceResults.FirstOrDefault(i => i.AttendanceTypeStatusID == System.Convert.ToInt32(value)).AttendanceTypeStatusCD;
}
if (attStatusId == "Absent")
{
return "A";
}
else if (attStatusId == "Present")
{
return "P";
}
else
{
return "L";
}
}
异常截图
假设我正确理解了您的问题,那么标准方法是创建另一个仅获取 属性 的 returns 有条件存在或不存在的事件,然后引发 属性 更改事件对于那个习俗 属性 当实际 属性 改变时。
A Converter 将是一个很好的解决方案。易于创建和修改。
尝试类似 -
<ListView x:Name="list1" ItemsSource="{Binding StudentList}">
<ListView.ItemTemplate >
<DataTemplate>
<ViewCell>
<StackLayout>
<Label VerticalTextAlignment="Center"
Text="{Binding StudentName}" />
<Button x:Name="mybtn"
BindingContext="{Binding Source={x:Reference list1}, Path=BindingContext}"
Command="{Binding BtnTextCommand}"
CommandParameter="{Binding Source={x:Reference mybtn}}"
Text="{Binding PresentBool, Converter={StaticResource PresentToString}}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
然后创建一个新的 class 实现 IValueConverter -
public class PresentToString : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (bool)value ? "Present" : "Absent";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
要像上面那样将其用作 StaticResource,您需要将其包含在相关资源字典中。您可以将其放在此 ListView 来自的 Page/ContentView -
<ContentView>
<ContentView.Resources>
<PresentToString x:Key="PresentToString" />
</ContentView.Resources>
<ListView x:Name="list1" ... >
...
这就是全部!如果您的转换器位于不同的命名空间中,则必须将 xaml 添加到 Page/ContentView.
编辑
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var typedValue = (int)value;
// Since ints are not nullable, we don't need to do a null check
switch (typedValue)
{
case 1:
return "P";
case 2:
return "L";
// case 0 handled in default. Removed to avoid redundancy.
default:
return "A";
}
}
我猜你的 Student
模型必须包含 ID 属性。您是说当 ID 的值不为 null 时要将按钮的文本设置为 Present,而另一方面将其设置为 Absent 吗?
如果是,则不应更改按钮的绑定上下文。当您想在视图模型而不是学生模型中触发此命令时,您只能更改命令的源。这是我的 XAML 供您参考:
<ContentPage.Resources>
<local:IDToStringConverter x:Key="IDToStringConverter"/>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout>
<ListView x:Name="list1" ItemsSource="{Binding StudentList}" HasUnevenRows="True">
<ListView.ItemTemplate >
<DataTemplate>
<ViewCell>
<StackLayout>
<Label VerticalTextAlignment="Center"
Text="{Binding StudentName}" />
<Button x:Name="mybtn"
Command="{Binding BindingContext.BtnTextCommand, Source={x:Reference list1}}"
CommandParameter="{Binding Source={x:Reference mybtn}}"
Text="{Binding ID, Converter={x:StaticResource IDToStringConverter}}"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
转换器实现 returns 不同字符串取决于 ID 值的效果:
public class IDToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null)
{
return "Present";
}
return "Absent";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
更新:
如果你想在运行时存储一些数据,你可以创建一个静态的 class:
public static class UtiClass
{
public static List<AttendanceStatusModel> AttendanceStatus { set; get; }
}
在推送到第 2 页之前设置它的值:UtiClass.AttendanceStatus = //...
。然后您可以在该设置后的任何其他地方访问它。即在您的转换器中。
我正在使用 Prism MVVM 将 ItemSource
绑定到 ListView
。这是列表 Cell
<ListView x:Name="list1" ItemsSource="{Binding StudentList}">
<ListView.ItemTemplate >
<DataTemplate>
<ViewCell>
<StackLayout>
<Label VerticalTextAlignment="Center"
Text="{Binding StudentName}" />
<Button x:Name="mybtn"
BindingContext="{Binding Source={x:Reference list1}, Path=BindingContext}"
Command="{Binding BtnTextCommand}"
CommandParameter="{Binding Source={x:Reference mybtn}}"
Text="{Binding BtnText}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
这是 ViewModel
private List<Student> _studentList;
public List<Student> StudentList
{
get { return _studentList; }
set { SetProperty(ref _studentList, value); }
}
我想在绑定之前为每个列表项每次修改按钮 Text
。我怎样才能从 ViewModel
Class 获取 BtnText
的更新值?
修改值表示如果Text
有ID value
则显示'Present'如果为空则显示'Absent'等
学生Class
public class Student
{
public Mychildren MyKid { get; set; }
public string LocalStudentId { get; set; }
public int? StudentId { get; set; }
public string StudentName { get; set; }
public int? AttendanceTypeStatusId { get; set; }
public int? StudentDailyAttendanceId { get; set; }
public int? AbsentReasonId { get; set; }
public string AttendanceTypeStatusCD { get; set; }}
}
编辑:
我已经在 Converter 中编写了这个逻辑,在 value
else
部分抛出异常
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string attStatusId = string.Empty;
//AttendanceTypeStatusId
if (value != null)
{
attStatusId = "Present";
}
else
{
attStatusId = SISConst.AttendanceResults.FirstOrDefault(i => i.AttendanceTypeStatusID == System.Convert.ToInt32(value)).AttendanceTypeStatusCD;
}
if (attStatusId == "Absent")
{
return "A";
}
else if (attStatusId == "Present")
{
return "P";
}
else
{
return "L";
}
}
异常截图
假设我正确理解了您的问题,那么标准方法是创建另一个仅获取 属性 的 returns 有条件存在或不存在的事件,然后引发 属性 更改事件对于那个习俗 属性 当实际 属性 改变时。
A Converter 将是一个很好的解决方案。易于创建和修改。
尝试类似 -
<ListView x:Name="list1" ItemsSource="{Binding StudentList}">
<ListView.ItemTemplate >
<DataTemplate>
<ViewCell>
<StackLayout>
<Label VerticalTextAlignment="Center"
Text="{Binding StudentName}" />
<Button x:Name="mybtn"
BindingContext="{Binding Source={x:Reference list1}, Path=BindingContext}"
Command="{Binding BtnTextCommand}"
CommandParameter="{Binding Source={x:Reference mybtn}}"
Text="{Binding PresentBool, Converter={StaticResource PresentToString}}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
然后创建一个新的 class 实现 IValueConverter -
public class PresentToString : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (bool)value ? "Present" : "Absent";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
要像上面那样将其用作 StaticResource,您需要将其包含在相关资源字典中。您可以将其放在此 ListView 来自的 Page/ContentView -
<ContentView>
<ContentView.Resources>
<PresentToString x:Key="PresentToString" />
</ContentView.Resources>
<ListView x:Name="list1" ... >
...
这就是全部!如果您的转换器位于不同的命名空间中,则必须将 xaml 添加到 Page/ContentView.
编辑
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var typedValue = (int)value;
// Since ints are not nullable, we don't need to do a null check
switch (typedValue)
{
case 1:
return "P";
case 2:
return "L";
// case 0 handled in default. Removed to avoid redundancy.
default:
return "A";
}
}
我猜你的 Student
模型必须包含 ID 属性。您是说当 ID 的值不为 null 时要将按钮的文本设置为 Present,而另一方面将其设置为 Absent 吗?
如果是,则不应更改按钮的绑定上下文。当您想在视图模型而不是学生模型中触发此命令时,您只能更改命令的源。这是我的 XAML 供您参考:
<ContentPage.Resources>
<local:IDToStringConverter x:Key="IDToStringConverter"/>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout>
<ListView x:Name="list1" ItemsSource="{Binding StudentList}" HasUnevenRows="True">
<ListView.ItemTemplate >
<DataTemplate>
<ViewCell>
<StackLayout>
<Label VerticalTextAlignment="Center"
Text="{Binding StudentName}" />
<Button x:Name="mybtn"
Command="{Binding BindingContext.BtnTextCommand, Source={x:Reference list1}}"
CommandParameter="{Binding Source={x:Reference mybtn}}"
Text="{Binding ID, Converter={x:StaticResource IDToStringConverter}}"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
转换器实现 returns 不同字符串取决于 ID 值的效果:
public class IDToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null)
{
return "Present";
}
return "Absent";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
更新:
如果你想在运行时存储一些数据,你可以创建一个静态的 class:
public static class UtiClass
{
public static List<AttendanceStatusModel> AttendanceStatus { set; get; }
}
在推送到第 2 页之前设置它的值:UtiClass.AttendanceStatus = //...
。然后您可以在该设置后的任何其他地方访问它。即在您的转换器中。