<RadioButton x:Name="radioButtonJpg" Content="JPG" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0 0 5 0" IsChecked="{Binding Path=Options.Format, Converter={StaticResource EnumBooleanConverter}, ConverterParameter=Jpg}"/>
<RadioButton x:Name="radioButtonPng" Content="PNG" HorizontalAlignment="Left" VerticalAlignment="Top" IsChecked="{Binding Path=Options.Format, Converter={StaticResource EnumBooleanConverter}, ConverterParameter=Png}"/>
</StackPanel>
- <CheckBox x:Name="checkBoxAnimationGif" Content="{x:Static proprties:Resources.OptionView_Animation_GIF}" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="1" Grid.Column="1" Margin="0 5 0 0" IsChecked="{Binding Options.AnimationGif}"/>
+ <CheckBox x:Name="checkBoxAnimationGif" Content="{x:Static proprties:Resources.OptionView_Animation_GIF}" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="1" Grid.Column="1" Margin="0 5 0 0" IsChecked="{Binding AnimationGif}"/>
</Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="0 0 0 5">
<Label x:Name="labelInterval" Content="{x:Static proprties:Resources.OptionView_Interval}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0 0 5 0" />
- <TextBox x:Name="textBoxInterval" HorizontalAlignment="Left" Text="{Binding Options.Interval}" VerticalAlignment="Center" Width="41" TextAlignment="Right" Margin="0 0 5 0"/>
+ <TextBox x:Name="textBoxInterval" HorizontalAlignment="Left" Text="{Binding Interval, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center" Width="41" TextAlignment="Right" Margin="0 0 5 0"/>
<Label x:Name="labelMs" Content="ms" HorizontalAlignment="Left" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Orientation="Horizontal" Margin="0 0 0 15">
<Label x:Name="labelRingBuffer" Content="{x:Static proprties:Resources.OptionView_Ring_buffer}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0 0 5 0"/>
- <TextBox x:Name="textBoxRingBuffer" HorizontalAlignment="Left" Text="{Binding Options.RingBuffer}" VerticalAlignment="Center" Width="41" TextAlignment="Right" Margin="0 0 5 0"/>
+ <TextBox x:Name="textBoxRingBuffer" HorizontalAlignment="Left" Text="{Binding RingBuffer, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center" Width="41" TextAlignment="Right" Margin="0 0 5 0"/>
<Label x:Name="labelFrames" Content="{x:Static proprties:Resources.OptionView_Frames}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
</StackPanel>
<Grid Margin="0 0 0 15">
// limitations under the License.
using System;
+using System.Collections;
using System.Collections.Generic;
+using System.ComponentModel;
using System.Linq;
+using System.Runtime.CompilerServices;
using System.Windows.Input;
+using BurageSnap.Properties;
using Prism.Commands;
using Prism.Interactivity.InteractionRequest;
using Prism.Mvvm;
namespace BurageSnap
{
- public class OptionViewModel : BindableBase, IInteractionRequestAware
+ public class OptionViewModel : BindableBase, IInteractionRequestAware, INotifyDataErrorInfo
{
private INotification _notification;
set
{
Options = (OptionContent)value.Content;
+ Interval = Options.Interval.ToString();
+ RingBuffer = Options.RingBuffer.ToString();
+ AnimationGif = Options.AnimationGif;
Modifier = new KeyModifier {Value = Options.HotKeyModifier};
HotKey = Options.HotKey;
SetProperty(ref _notification, value);
set { SetProperty(ref _options, value); }
}
+ private string _interval;
+
+ public string Interval
+ {
+ get { return _interval; }
+ set
+ {
+ SetProperty(ref _interval, value);
+ int result;
+ if (!int.TryParse(_interval, out result) || result < 10 || result > 1000 * 1000)
+ {
+ SetError(Resources.OptionView_Validate_interval);
+ }
+ else
+ {
+ ClearError();
+ }
+ _options.Interval = result;
+ }
+ }
+
+ private string _ringBuffer;
+
+ public string RingBuffer
+ {
+ get { return _ringBuffer; }
+ set
+ {
+ SetProperty(ref _ringBuffer, value);
+ int result;
+ if (!int.TryParse(value, out result) || result < 0 || result > 100)
+ {
+ SetError(Resources.OptionView_Validate_ring_buffer);
+ }
+ else if (_options.AnimationGif && result < 2)
+ {
+ SetError(Resources.OptionView_Validate_ring_buffer_for_animation_GIF);
+ }
+ else
+ {
+ ClearError();
+ }
+ _options.RingBuffer = result;
+ }
+ }
+
+ private bool _animationGif;
+
+ public bool AnimationGif
+ {
+ get { return _animationGif; }
+ set
+ {
+ SetProperty(ref _animationGif, value);
+ if (value && _options.RingBuffer <= 1)
+ {
+ // ReSharper disable once ExplicitCallerInfoArgument
+ SetError(Resources.OptionView_Validate_ring_buffer_for_animation_GIF, nameof(RingBuffer));
+ }
+ else
+ {
+ // ReSharper disable once ExplicitCallerInfoArgument
+ ClearError(nameof(RingBuffer));
+ }
+ _options.AnimationGif = value;
+ }
+ }
+
private string _title;
public string Title
public bool IsKeySelected => HotKey != "";
- public ICommand OkCommand { get; private set; }
+ private readonly ErrorsContainer<string> _errors;
+
+ public ICommand OkCommand { get; }
public ICommand CancelCommand { get; private set; }
public ICommand SelectedCommand { get; private set; }
public ICommand AddTitleCommand { get; private set; }
public OptionViewModel()
{
- OkCommand = new DelegateCommand(OkInteraction);
+ _errors = new ErrorsContainer<string>(OnErrorsChanged);
+
+ OkCommand = new DelegateCommand(OkInteraction, () => !HasErrors);
CancelCommand = new DelegateCommand(CancelInteraction);
SelectedCommand = new DelegateCommand<object[]>(Selected);
AddTitleCommand = new DelegateCommand(AddTitle);
{
WindowPicker.Stop();
}
+
+ public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
+
+ public bool HasErrors => _errors.HasErrors;
+
+ public IEnumerable GetErrors(string propertyName)
+ {
+ return _errors.GetErrors(propertyName);
+ }
+
+ private void OnErrorsChanged([CallerMemberName] string propertyName = null)
+ {
+ ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
+ ((DelegateCommand)OkCommand).RaiseCanExecuteChanged();
+ }
+
+ private void SetError(string message, [CallerMemberName] string propertyName = null)
+ {
+ _errors.SetErrors(propertyName, new [] {message});
+ }
+
+ private void ClearError([CallerMemberName] string propertyName = null)
+ {
+ _errors.ClearErrors(propertyName);
+ }
}
}
\ No newline at end of file
return ResourceManager.GetString("OptionView_Interval", resourceCulture);
}
}
-
+
/// <summary>
- /// Option に類似しているローカライズされた文字列を検索します。
+ /// Notify に類似しているローカライズされた文字列を検索します。
/// </summary>
- public static string OptionView_Option {
+ public static string OptionView_Notify {
get {
- return ResourceManager.GetString("OptionView_Option", resourceCulture);
+ return ResourceManager.GetString("OptionView_Notify", resourceCulture);
}
}
-
+
/// <summary>
- /// Notify に類似しているローカライズされた文字列を検索します。
+ /// Option に類似しているローカライズされた文字列を検索します。
/// </summary>
- public static string OptionView_Notify {
+ public static string OptionView_Option {
get {
- return ResourceManager.GetString("OptionView_Notify", resourceCulture);
+ return ResourceManager.GetString("OptionView_Option", resourceCulture);
}
}
}
/// <summary>
+ /// Interval must be in the range of 10 ms to 1000 sec. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ public static string OptionView_Validate_interval {
+ get {
+ return ResourceManager.GetString("OptionView_Validate_interval", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// The size of the ring buffer must be in the range of 0 to 100. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ public static string OptionView_Validate_ring_buffer {
+ get {
+ return ResourceManager.GetString("OptionView_Validate_ring_buffer", resourceCulture);
+ }
+ }
+
+ /// <summary>
+ /// The size of the ring buffer must be greater than 1 to generate animation GIF. に類似しているローカライズされた文字列を検索します。
+ /// </summary>
+ public static string OptionView_Validate_ring_buffer_for_animation_GIF {
+ get {
+ return ResourceManager.GetString("OptionView_Validate_ring_buffer_for_animation_GIF", resourceCulture);
+ }
+ }
+
+ /// <summary>
/// Window: に類似しているローカライズされた文字列を検索します。
/// </summary>
public static string OptionView_Window {