C# 在绑定到ListView之前修改ViewModel中的属性

C# 在绑定到ListView之前修改ViewModel中的属性,c#,xamarin,mvvm,xamarin.forms,prism,C#,Xamarin,Mvvm,Xamarin.forms,Prism,我正在使用Prism MVVM将ItemSource绑定到ListView。这是列表单元格 <ListView x:Name="list1" ItemsSource="{Binding StudentList}"> <ListView.ItemTemplate > <DataTemplate> <ViewCell> <StackLayout> <Lab

我正在使用Prism MVVM将
ItemSource
绑定到
ListView
。这是列表
单元格

<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
类获取
BtnText
的更新值

修改值意味着如果
文本
具有ID
则显示“存在”,如果为空则显示“不存在”等

学生班

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; }}
}
编辑:

我已经在转换器中编写了这个逻辑,在第一个
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";
    }
}
宽恕


假设我正确理解了您的问题,那么标准的方法是创建另一个有条件返回Present或缺席的get-only属性,然后在实际属性更改时为该自定义属性引发属性更改事件。

A将是一个很好的解决方案。易于创建和修改

试着做些类似-

<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>
要像我上面提到的那样将其用作静态资源,您需要将其包含在相关的资源字典中。您可以将它放在该ListView来自的页面/内容视图上-

<ContentView>
    <ContentView.Resources>
        <PresentToString x:Key="PresentToString" />
    </ContentView.Resources>

    <ListView x:Name="list1" ... >
...

我猜您的
学生
模型必须包含ID属性。您的意思是要将按钮的文本设置为在ID值不为null时显示,另一方面将其设置为不存在吗

如果是这样,则不应更改按钮的绑定上下文。只有在视图模型(而不是学生模型)中启动此命令时,才能更改命令的源。以下是我的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>
更新:

如果要在运行时存储一些数据,可以创建一个静态类:

public static class UtiClass
{
    public static List<AttendanceStatusModel> AttendanceStatus { set; get; }
}
公共静态类
{
公共静态列表AttendanceStatus{set;get;}
}

在进入第2页之前设置它的值:
UtiClass.AttendanceStatus=//…
。然后,在设置之后,您可以在其他任何地方访问它。i、 e.在您的转换器中。

可能会创建一个名为BindableModel的新模型,并使用此模型填充ListView,在该模型中,根据您的条件分配值?您看过值转换器了吗?
buttonexthold
的作用是什么?更改
buttonexthold
时,请将其删除或为
buttonext
提高
PropertyChanged
。谢谢您的回答。但我有一种复杂的逻辑来操纵价值观。如果你想看的话,我会用ViewModel更新我的问题。我假设你的“学生”课有某种布尔运算或方法来判断学生是否缺席。只要您的值被正确绑定,视图就应该相应地更新。在上面的Edit2中,我不确定“在值的第一个其他部分中抛出异常”是什么意思。我认为这可能是一个键入问题,因为
是一个
对象
,您正在将其与
字符串
进行比较。我会相应地更新我的答案。但我还是有例外。请看我问题中附带的屏幕截图。您应该能够完全删除该行。至于它为什么为null,这一定是XAML代码的绑定问题。仔细检查你的XAML,如果没有发现任何错误,请发布一个屏幕截图。谢谢你的回答。请检查我更新的问题和描述。@Arvindraja正如我上面所说的,没有必要在视图模型中处理代码。将按钮的文本直接绑定到您的
AttendanceTypeStatusId
。然后在转换器中操作它。你想要什么就给我什么。我认为您应该这样做,因为每个项都有自己的
AttendanceTypeStatusId
,您不能将逻辑放在视图模型中。我有
AttendanceStatus
List
,您能告诉我在converter类中获取列表数据的好方法吗。我的意思是在哪里调用服务来获取
AttendanceStatus
数据?@Arvindraja
AttendanceStatus
用于什么?你把那个列表放在哪里了?这个列表只有两个字段
AttendanceTypeStatusID
AttendanceTypeStatusCD
,根据ID,我得到了缺席、出席、迟到等文本。我总是有三条ID为的记录。
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";
    }
}
<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>
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();
    }
}
public static class UtiClass
{
    public static List<AttendanceStatusModel> AttendanceStatus { set; get; }
}