Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Vraag nu de assistent om de pagina te maken. Benoem de gewenste WinUI-besturingselementen, zodat deze niet worden vervangen door een besturingselement uit een ander UI-framework.
Vraag om de XAML
Gebruik deze prompt:
Create MainPage.xaml for TaskTally.
- Use a TextBox with a visible Header and an Add task Button.
- Use ListView for the task collection. Don't wrap it in ScrollViewer.
- In each row, use a CheckBox, task title, and delete Button.
- Use InfoBar for save and error status.
- Use x:Bind and specify Mode for every binding that changes.
- For TextBox.Text, use Mode=TwoWay and
UpdateSourceTrigger=PropertyChanged.
- Add accessible names and tooltips for icon-only commands.
- Add an empty state.
- At widths below 640 effective pixels, move the Add task button
below the TextBox and stretch it.
- Use theme resources instead of hard-coded colors.
- Build and fix all XAML compiler and analyzer warnings.
Inspecteer deze details in de gegenereerde XAML.
Gegevensinvoer
<TextBox
x:Name="NewTaskTextBox"
Header="New task"
PlaceholderText="For example, review the generated XAML"
Text="{x:Bind ViewModel.NewTaskTitle, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
<Button
x:Name="AddTaskButton"
Grid.Column="1"
VerticalAlignment="Bottom"
AutomationProperties.Name="Add task"
Command="{x:Bind ViewModel.AddTaskCommand}"
Content="Add task" />
De zichtbare Header betekent dat het invoerveld niet uitsluitend afhankelijk is van placeholdertekst als enige label.
UpdateSourceTrigger=PropertyChanged werkt het viewmodel bij terwijl de gebruiker typt, zodat de opdracht onmiddellijk kan worden ingeschakeld.
Taakverzameling
Definieer een getypte gegevenssjabloon:
<DataTemplate x:Key="TaskTemplate" x:DataType="models:TaskItem">
<Grid Padding="8" ColumnSpacing="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<CheckBox
VerticalAlignment="Center"
AutomationProperties.Name="{x:Bind Title}"
Click="TaskCheckBox_Click"
IsChecked="{x:Bind IsComplete, Mode=TwoWay}" />
<TextBlock
Grid.Column="1"
VerticalAlignment="Center"
Text="{x:Bind Title}" />
<Button
Grid.Column="2"
VerticalAlignment="Center"
AutomationProperties.Name="{x:Bind local:MainPage.DeleteTaskName(Title),
Mode=OneWay}"
Click="DeleteButton_Click"
DataContext="{x:Bind}"
ToolTipService.ToolTip="Delete task">
<FontIcon Glyph="" />
</Button>
</Grid>
</DataTemplate>
Gebruik een statische functie om de taaktitel op te nemen in de automatiseringsnaam van de knop Verwijderen, zodat een schermlezer onderscheid kan maken tussen rijen:
public static string DeleteTaskName(string title) => $"Delete {title}";
Bind vervolgens de verzameling:
<ListView
AutomationProperties.Name="Tasks"
ItemTemplate="{StaticResource TaskTemplate}"
ItemsSource="{x:Bind ViewModel.Tasks, Mode=OneWay}"
SelectionMode="None" />
ListView biedt schuiffunctionaliteit en gebruikersinterfacevirtualisatie. Het inpakken ervan in een ScrollViewer verstoort beide.
Meer informatie: ListView en GridView en Gegevensbinding met XAML.
Status en lege toestand
Gebruiken InfoBar voor een niet-blokkeringsstatusbericht:
<InfoBar
IsClosable="True"
IsOpen="{x:Bind ViewModel.IsStatusOpen, Mode=TwoWay}"
Message="{x:Bind ViewModel.StatusMessage, Mode=OneWay}"
Severity="{x:Bind local:MainPage.StatusSeverity(ViewModel.HasError),
Mode=OneWay}" />
Gebruik een statische functie om de Booleaanse waarde voor de lege status naar Visibility te converteren zonder een converterklasse toe te voegen:
public static Visibility BoolToVisibility(bool value) =>
value ? Visibility.Visible : Visibility.Collapsed;
public static InfoBarSeverity StatusSeverity(bool hasError) =>
hasError ? InfoBarSeverity.Error : InfoBarSeverity.Success;
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="Add a task to get started."
Visibility="{x:Bind local:MainPage.BoolToVisibility(ViewModel.HasNoTasks),
Mode=OneWay}" />
Voer de app uit voordat u gegevens toevoegt en controleer of de lege status leeg is en de knop Taak toevoegen is uitgeschakeld:
Adaptieve indeling
Gebruik visuele statussen om de knop onder de invoer te verplaatsen:
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="Narrow">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="AddTaskButton.(Grid.Row)" Value="1" />
<Setter Target="AddTaskButton.(Grid.Column)" Value="0" />
<Setter Target="AddTaskButton.HorizontalAlignment" Value="Stretch" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Standard">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="640" />
</VisualState.StateTriggers>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
Pas het formaat van de actieve toepassing aan over het breakpoint heen. Een responsieve claim in een prompt is geen bewijs dat de indeling werkt.
Meer informatie: Responsieve indelingen met XAML.
Aanzichtspecifieke gebeurtenissen koppelen
De pagina laadt persistente gegevens eenmaal en delegeert taakwijzigingen aan het weergavemodel:
public sealed partial class MainPage : Page
{
public MainPageViewModel ViewModel { get; } = new();
public MainPage()
{
InitializeComponent();
Loaded += MainPage_Loaded;
}
private async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
Loaded -= MainPage_Loaded;
await ViewModel.InitializeAsync();
NewTaskTextBox.Focus(FocusState.Programmatic);
}
private async void TaskCheckBox_Click(object sender, RoutedEventArgs e)
{
await ViewModel.TaskCompletionChangedAsync();
}
private async void DeleteButton_Click(object sender, RoutedEventArgs e)
{
if (sender is Button { DataContext: TaskItem task })
{
await ViewModel.DeleteTaskCommand.ExecuteAsync(task);
}
}
}
Gebeurtenis-handlers met een async void retourtype zijn hier geschikt omdat XAML-gebeurtenissen vereisen void. Andere asynchrone methoden in de app retourneren Task.
Bouwen en uitvoeren
Bouw de app, start deze via het bijbehorende pakket en test elk acceptatiecriterium dat nu is geïmplementeerd:
- Voeg een taak toe met de muis.
- Voeg een taak toe met alleen het toetsenbord.
- Een taak voltooien en verwijderen.
- Sluit de app en start deze opnieuw om persistentie te controleren.
- Pas het formaat van het venster onder en boven de 640 effectieve pixels aan.
- Schakelen tussen licht, donker en een contrastthema.
Windows developer