Изменить свойство из ViewModel перед привязкой к ListView - PullRequest
1 голос
/ 14 мая 2019

Я связываю ItemSource с ListView с помощью Prism MVVM. Это список 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 имеет идентификатор value, тогда отображается «Присутствует», если ноль, затем отображается «Отсутствует» и т. Д.

Студенческий класс

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 часть в value

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";
    }
}

ExcpetionScreenshot

enter image description here

Ответы [ 3 ]

2 голосов
/ 14 мая 2019

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>

Затем создайте новый класс, который реализует 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 какУ меня есть выше, вам нужно включить его в соответствующий словарь ресурсов.Вы можете поместить это в Page / ContentView, откуда этот ListView - -

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

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

И это должно быть все!Если ваш конвертер находится в другом пространстве имен, вам нужно добавить xaml include в Page / ContentView.

EDIT

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";
    }
}
1 голос
/ 15 мая 2019

Я полагаю, ваша Student модель должна содержать свойство ID.Вы имеете в виду, что вы хотите установить для кнопки текст «Представлять», когда значение идентификатора не равно нулю, и установить для него значение «Отсутствует» с другой стороны?

Если это так, вам не следует изменять контекст привязки кнопки.Вы можете изменить источник команды только в том случае, если хотите запустить эту команду в модели представления вместо модели Student.Вот мой 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 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; }
}

Установите его значение, прежде чем перейти на страницу 2: UtiClass.AttendanceStatus = //....После этого вы можете получить к нему доступ где угодно.т.е. в вашем конвертере.

1 голос
/ 14 мая 2019

Предполагая, что я правильно понимаю ваш вопрос, стандартный способ сделать это - создать другое свойство get only, которое условно возвращает Present или Absent, а затем вызвать событие измененного свойства для этого пользовательского свойства при изменении фактического свойства.

...