mirror of
https://github.com/chylex/Discord-History-Tracker.git
synced 2025-04-18 01:12:22 +03:00
Add TextBoxDialog
This commit is contained in:
parent
daa2feb445
commit
de5a8b690b
@ -7,6 +7,7 @@
|
||||
<entry key="Desktop/Dialogs/CheckBox/CheckBoxDialog.axaml" value="Desktop/Desktop.csproj" />
|
||||
<entry key="Desktop/Dialogs/Message/MessageDialog.axaml" value="Desktop/Desktop.csproj" />
|
||||
<entry key="Desktop/Dialogs/Progress/ProgressDialog.axaml" value="Desktop/Desktop.csproj" />
|
||||
<entry key="Desktop/Dialogs/TextBox/TextBoxDialog.axaml" value="Desktop/Desktop.csproj" />
|
||||
<entry key="Desktop/Main/AboutWindow.axaml" value="Desktop/Desktop.csproj" />
|
||||
<entry key="Desktop/Main/Controls/AttachmentFilterPanel.axaml" value="Desktop/Desktop.csproj" />
|
||||
<entry key="Desktop/Main/Controls/MessageFilterPanel.axaml" value="Desktop/Desktop.csproj" />
|
||||
|
@ -7,7 +7,7 @@
|
||||
<Application.Styles>
|
||||
|
||||
<FluentTheme Mode="Light" />
|
||||
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Default.xaml"/>
|
||||
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Default.xaml" />
|
||||
|
||||
<Style Selector="Button, CheckBox, RadioButton, Expander /template/ ToggleButton#ExpanderHeader">
|
||||
<Setter Property="Cursor" Value="Hand" />
|
||||
@ -36,6 +36,20 @@
|
||||
<Style Selector="TextBox:disabled"><!-- TODO bug in Avalonia (https://github.com/AvaloniaUI/Avalonia/pull/7792) -->
|
||||
<Setter Property="Foreground" Value="{DynamicResource TextControlForegroundDisabled}" />
|
||||
</Style>
|
||||
<Style Selector="TextBox:error DataValidationErrors">
|
||||
<Style.Resources>
|
||||
<ControlTemplate x:Key="InlineDataValidationContentTemplate" TargetType="DataValidationErrors">
|
||||
<ContentPresenter Name="PART_ContentPresenter"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}"
|
||||
Content="{TemplateBinding Content}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}" />
|
||||
</ControlTemplate>
|
||||
</Style.Resources>
|
||||
<Setter Property="Template" Value="{StaticResource InlineDataValidationContentTemplate}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="Expander /template/ ToggleButton#ExpanderHeader">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Left" />
|
||||
|
@ -31,6 +31,10 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Version.cs" Link="Version.cs" />
|
||||
<Compile Update="Dialogs\TextBox\TextBoxDialog.axaml.cs">
|
||||
<DependentUpon>CheckBoxDialog.axaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AvaloniaResource Include="Resources/icon.ico" />
|
||||
|
56
app/Desktop/Dialogs/TextBox/TextBoxDialog.axaml
Normal file
56
app/Desktop/Dialogs/TextBox/TextBoxDialog.axaml
Normal file
@ -0,0 +1,56 @@
|
||||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:namespace="clr-namespace:DHT.Desktop.Dialogs.TextBox"
|
||||
mc:Ignorable="d" d:DesignWidth="500"
|
||||
x:Class="DHT.Desktop.Dialogs.TextBox.TextBoxDialog"
|
||||
Title="{Binding Title}"
|
||||
Icon="avares://DiscordHistoryTracker/Resources/icon.ico"
|
||||
Width="500" SizeToContent="Height" CanResize="False"
|
||||
WindowStartupLocation="CenterOwner">
|
||||
|
||||
<Window.DataContext>
|
||||
<namespace:TextBoxDialogModel />
|
||||
</Window.DataContext>
|
||||
|
||||
<Window.Styles>
|
||||
<Style Selector="Panel.buttons">
|
||||
<Setter Property="Margin" Value="0 20 0 0" />
|
||||
</Style>
|
||||
<Style Selector="Panel.buttons > WrapPanel.right">
|
||||
<Setter Property="HorizontalAlignment" Value="Right" />
|
||||
</Style>
|
||||
<Style Selector="Panel.buttons Button">
|
||||
<Setter Property="MinWidth" Value="80" />
|
||||
<Setter Property="Margin" Value="8 0 0 0" />
|
||||
</Style>
|
||||
</Window.Styles>
|
||||
|
||||
<StackPanel Margin="20">
|
||||
<ScrollViewer MaxHeight="400">
|
||||
<StackPanel Spacing="10">
|
||||
<TextBlock Text="{Binding Description}" TextWrapping="Wrap" />
|
||||
<ItemsRepeater Items="{Binding Items}">
|
||||
<ItemsRepeater.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<DockPanel Margin="0 5 25 0">
|
||||
<TextBox Name="Input" Text="{Binding Value}" Width="180" VerticalAlignment="Top" DockPanel.Dock="Right" />
|
||||
<Label Target="Input" VerticalAlignment="Center" DockPanel.Dock="Left">
|
||||
<TextBlock Text="{Binding Title}" TextWrapping="Wrap" />
|
||||
</Label>
|
||||
</DockPanel>
|
||||
</DataTemplate>
|
||||
</ItemsRepeater.ItemTemplate>
|
||||
</ItemsRepeater>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
<Panel Classes="buttons">
|
||||
<WrapPanel Classes="right">
|
||||
<Button Click="ClickOk" IsEnabled="{Binding !HasErrors}">OK</Button>
|
||||
<Button Click="ClickCancel">Cancel</Button>
|
||||
</WrapPanel>
|
||||
</Panel>
|
||||
</StackPanel>
|
||||
|
||||
</Window>
|
31
app/Desktop/Dialogs/TextBox/TextBoxDialog.axaml.cs
Normal file
31
app/Desktop/Dialogs/TextBox/TextBoxDialog.axaml.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using DHT.Desktop.Dialogs.Message;
|
||||
|
||||
namespace DHT.Desktop.Dialogs.TextBox {
|
||||
[SuppressMessage("ReSharper", "MemberCanBeInternal")]
|
||||
public sealed class TextBoxDialog : Window {
|
||||
public TextBoxDialog() {
|
||||
InitializeComponent();
|
||||
#if DEBUG
|
||||
this.AttachDevTools();
|
||||
#endif
|
||||
}
|
||||
|
||||
private void InitializeComponent() {
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public void ClickOk(object? sender, RoutedEventArgs e) {
|
||||
Close(DialogResult.OkCancel.Ok);
|
||||
}
|
||||
|
||||
public void ClickCancel(object? sender, RoutedEventArgs e) {
|
||||
Close(DialogResult.OkCancel.Cancel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
47
app/Desktop/Dialogs/TextBox/TextBoxDialogModel.cs
Normal file
47
app/Desktop/Dialogs/TextBox/TextBoxDialogModel.cs
Normal file
@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using DHT.Utils.Models;
|
||||
|
||||
namespace DHT.Desktop.Dialogs.TextBox {
|
||||
class TextBoxDialogModel : BaseModel {
|
||||
public string Title { get; init; } = "";
|
||||
public string Description { get; init; } = "";
|
||||
|
||||
private IReadOnlyList<TextBoxItem> items = Array.Empty<TextBoxItem>();
|
||||
|
||||
public IReadOnlyList<TextBoxItem> Items {
|
||||
get => items;
|
||||
|
||||
protected set {
|
||||
foreach (var item in items) {
|
||||
item.ErrorsChanged -= OnItemErrorsChanged;
|
||||
}
|
||||
|
||||
items = value;
|
||||
|
||||
foreach (var item in items) {
|
||||
item.ErrorsChanged += OnItemErrorsChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasErrors => Items.Any(static item => !item.IsValid);
|
||||
|
||||
private void OnItemErrorsChanged(object? sender, DataErrorsChangedEventArgs e) {
|
||||
OnPropertyChanged(nameof(HasErrors));
|
||||
}
|
||||
}
|
||||
|
||||
sealed class TextBoxDialogModel<T> : TextBoxDialogModel {
|
||||
public new IReadOnlyList<TextBoxItem<T>> Items { get; }
|
||||
|
||||
public IEnumerable<TextBoxItem<T>> ValidItems => Items.Where(static item => item.IsValid);
|
||||
|
||||
public TextBoxDialogModel(IEnumerable<TextBoxItem<T>> items) {
|
||||
this.Items = new List<TextBoxItem<T>>(items);
|
||||
base.Items = this.Items;
|
||||
}
|
||||
}
|
||||
}
|
42
app/Desktop/Dialogs/TextBox/TextBoxItem.cs
Normal file
42
app/Desktop/Dialogs/TextBox/TextBoxItem.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using DHT.Utils.Models;
|
||||
|
||||
namespace DHT.Desktop.Dialogs.TextBox {
|
||||
class TextBoxItem : BaseModel, INotifyDataErrorInfo {
|
||||
public string Title { get; init; } = "";
|
||||
public object? Item { get; init; } = null;
|
||||
|
||||
public Func<string, bool> ValidityCheck { get; init; } = static _ => true;
|
||||
public bool IsValid => ValidityCheck(Value);
|
||||
|
||||
private string value = string.Empty;
|
||||
|
||||
public string Value {
|
||||
get => this.value;
|
||||
set {
|
||||
Change(ref this.value, value);
|
||||
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(nameof(Value)));
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable GetErrors(string? propertyName) {
|
||||
if (propertyName == nameof(Value) && !IsValid) {
|
||||
yield return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasErrors => !IsValid;
|
||||
public event EventHandler<DataErrorsChangedEventArgs>? ErrorsChanged;
|
||||
}
|
||||
|
||||
sealed class TextBoxItem<T> : TextBoxItem {
|
||||
public new T Item { get; }
|
||||
|
||||
public TextBoxItem(T item) {
|
||||
this.Item = item;
|
||||
base.Item = item;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user