Набор C # WPF MVVM выбран в xaml с приложением типа календаря - PullRequest
0 голосов
/ 11 февраля 2019

Я относительно новичок в WPF и MVVM, я написал только одно другое приложение MVVM.Я хотел бы создать собственное приложение-календарь, но у меня возникают проблемы с настройкой выбранного дня.

XAML

<Grid Background="White">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition/>
    </Grid.RowDefinitions>

    <Grid Grid.Row="0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="8*"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        <Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="3" >
            <TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Text="&lt;"></TextBlock>
        </Button>
        <Label HorizontalAlignment="Center" VerticalAlignment="Top" x:Name="CalendarTitle" Content="{Binding Path=DateTitle}" Grid.Column="1"/>
        <Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="3" Grid.Column="2" Content="&gt;"/>
    </Grid>

    <Grid Grid.Row="1">
        <ItemsControl ItemsSource="{Binding Days}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid Rows="5" Columns="7" FirstColumn="3"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Border BorderBrush="Black" BorderThickness="1">
                        <Grid Background="Transparent" MouseDown="Grid_MouseDown" MouseLeave="Grid_MouseLeave" MouseEnter="Grid_MouseEnter">
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition/>
                            </Grid.RowDefinitions>
                            <Label Content="{Binding DayNumber}"></Label>
                            <Label Content="{Binding Message}" VerticalAlignment="Center" HorizontalAlignment="Center"></Label>
                        </Grid>
                    </Border>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Grid>

Использование ItemsControlи привязка его ItemsSource к ObservableCollection будет работать с точным поднятием данных, как мне также правильно создать атрибут SelectedDay?

ViewModel

public class CalendarCellsViewModel : BaseINPC
{
    public CalendarCellsViewModel()
    {
        DateTitle = $"{CultureInfo.CurrentCulture.DateTimeFormat.GetAbbreviatedMonthName(DateTime.Today.Month)} {DateTime.Today.Year}";

        for(int i = 1; i <= 31; i++)
        {
            Days.Add(new CalendarDayData { DayNumber = i, Message = "Test" });
        }
    }

    private string _dateTitle;
    public string DateTitle
    {
        get { return _dateTitle; }
        set { SetProperty(ref _dateTitle, value); }
    }

    private ObservableCollection<CalendarDayData> _days = new ObservableCollection<CalendarDayData>();

    public ObservableCollection<CalendarDayData> Days
    {
        get { return _days; }
        set { SetProperty(ref _days, value); }
    }
}

Модель

public class CalendarDayData : BaseINPC
{
    public CalendarDayData()
    {

    }
    public int DayNumber { get; set; }
    public int ReminderStart { get; set; }
    public int ReminderFrequency { get; set; }
    public string Message { get; set; }

    private bool _selectedDay = false;
    public bool SelectedDay
    {
        get { return _selectedDay; }
        set
        {
            if (_selectedDay != value)
            {
                _selectedDay = value;
                SetProperty(ref _selectedDay, value);
            }
        }
    }
}

Любые советы или хорошие ресурсы, на которые я должен взглянуть?

1 Ответ

0 голосов
/ 11 февраля 2019

ItemsControl не поддерживает выбор.Вам нужно использовать ListBox для этого.С этим вы можете связать свойство SelectedItem вашего ListBox со свойством SelectedDay из вашей ViewModel .

XAML

<ListBox ItemsSource="{Binding Days}" SelectedItem="{Binding SelectedDay}">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Rows="5" Columns="7" FirstColumn="3"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Stretch">
                <StackPanel Background="Transparent" HorizontalAlignment="Stretch">
                    <Label Content="{Binding DayNumber}"/>
                    <Label Content="{Binding Message}" VerticalAlignment="Center" 
                           HorizontalAlignment="Center"/>
                </StackPanel>
            </Border>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Вы можете получить SelectedItem, имея свойство Bind в вашем ViewModel.Что-то вроде

ViewModel

public class CalendarCellsViewModel : INotifyPropertyChanged
{
    private string _dateTitle;
    private ObservableCollection<CalendarDayData> _days;
    private CalendarDayData _selectedDay;

    public string DateTitle
    {
        get { return _dateTitle; }
        set
        {
            _dateTitle = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(DateTitle)));
        }
    }
    public ObservableCollection<CalendarDayData> Days
    {
        get { return _days; }
        set
        {
            _days = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Days)));
        }
    }
    public CalendarDayData SelectedDay
    {
        get { return _selectedDay; }
        set
        {
            _selectedDay = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedDay)));
        }
    }

    public CalendarCellsViewModel()
    {
        DateTitle = $"{CultureInfo.CurrentCulture.DateTimeFormat.GetAbbreviatedMonthName(DateTime.Today.Month)} {DateTime.Today.Year}";
        Days = new ObservableCollection<CalendarDayData>();
        for (int i = 1; i <= 31; i++)
        {
            var day = new CalendarDayData { DayNumber = i, Message = "Test" };
            if (i == DateTime.Today.Day)
                SelectedDay = day;
            Days.Add(day);
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

Модель

public class CalendarDayData
{
    public int DayNumber { get; set; }
    public int ReminderStart { get; set; }
    public int ReminderFrequency { get; set; }
    public string Message { get; set; }
}

Дополнительно

Если вы хотите дифференцировать ваш SelectedItem, вы можете установить стиль ниже на Label.

<Label Content="{Binding DayNumber}">
    <Label.Style>
        <Style TargetType="Label">
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsSelected, 
                                               RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}" 
                             Value="True">
                    <Setter Property="FontWeight" Value="ExtraBold"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Label.Style>
</Label>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...