Skip to content

Commit 5a044a4

Browse files
authored
Trigger textbox changes in settings on lost focus (#289)
1 parent 2582ed3 commit 5a044a4

File tree

4 files changed

+106
-16
lines changed

4 files changed

+106
-16
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
using System;
2+
using Avalonia;
3+
using Avalonia.Controls;
4+
using Avalonia.Data;
5+
using Avalonia.Interactivity;
6+
using Avalonia.Xaml.Interactivity;
7+
8+
namespace LightBulb.Behaviors;
9+
10+
public class LostFocusUpdateBindingBehavior : Behavior<TextBox>
11+
{
12+
public static readonly StyledProperty<string?> TextProperty = AvaloniaProperty.Register<
13+
LostFocusUpdateBindingBehavior,
14+
string?
15+
>(nameof(Text), defaultBindingMode: BindingMode.TwoWay);
16+
17+
static LostFocusUpdateBindingBehavior()
18+
{
19+
TextProperty.Changed.Subscribe(args =>
20+
{
21+
if (args.Sender is LostFocusUpdateBindingBehavior behavior)
22+
behavior.OnBindingValueChanged();
23+
});
24+
}
25+
26+
public string? Text
27+
{
28+
get => GetValue(TextProperty);
29+
set => SetValue(TextProperty, value);
30+
}
31+
32+
protected override void OnAttached()
33+
{
34+
if (AssociatedObject is null)
35+
return;
36+
37+
AssociatedObject.LostFocus += OnLostFocus;
38+
base.OnAttached();
39+
}
40+
41+
protected override void OnDetaching()
42+
{
43+
if (AssociatedObject is null)
44+
return;
45+
46+
AssociatedObject.LostFocus -= OnLostFocus;
47+
base.OnDetaching();
48+
}
49+
50+
private void OnLostFocus(object? sender, RoutedEventArgs e)
51+
{
52+
if (AssociatedObject is null)
53+
return;
54+
55+
Text = AssociatedObject.Text;
56+
}
57+
58+
private void OnBindingValueChanged()
59+
{
60+
if (AssociatedObject != null)
61+
AssociatedObject.Text = Text;
62+
}
63+
}

LightBulb/LightBulb.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
<PackageReference Include="Avalonia" Version="11.0.10" />
2121
<PackageReference Include="Avalonia.Desktop" Version="11.0.10" />
2222
<PackageReference Include="Avalonia.Diagnostics" Version="11.0.10" Condition="'$(Configuration)' == 'Debug'" />
23+
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="11.0.10.6" />
2324
<PackageReference Include="Cogwheel" Version="2.0.4" />
2425
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
2526
<PackageReference Include="CSharpier.MsBuild" Version="0.28.0" PrivateAssets="all" />

LightBulb/Views/Components/Settings/GeneralSettingsTabView.axaml

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
x:Class="LightBulb.Views.Components.Settings.GeneralSettingsTabView"
33
xmlns="https://github.com/avaloniaui"
44
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5+
xmlns:behaviors="clr-namespace:LightBulb.Behaviors"
56
xmlns:converters="clr-namespace:LightBulb.Converters"
67
xmlns:settings="clr-namespace:LightBulb.ViewModels.Components.Settings">
78
<Design.DataContext>
@@ -15,8 +16,11 @@
1516
<TextBox
1617
MinWidth="24"
1718
HorizontalAlignment="Right"
18-
DockPanel.Dock="Right"
19-
Text="{Binding DayTemperature, Converter={x:Static converters:DoubleToStringConverter.Instance}}" />
19+
DockPanel.Dock="Right">
20+
<Interaction.Behaviors>
21+
<behaviors:LostFocusUpdateBindingBehavior Text="{Binding DayTemperature, Converter={x:Static converters:DoubleToStringConverter.Instance}}" />
22+
</Interaction.Behaviors>
23+
</TextBox>
2024
</DockPanel>
2125
<Slider
2226
Margin="0,12,0,0"
@@ -34,8 +38,11 @@
3438
<TextBox
3539
MinWidth="24"
3640
HorizontalAlignment="Right"
37-
DockPanel.Dock="Right"
38-
Text="{Binding NightTemperature, Converter={x:Static converters:DoubleToStringConverter.Instance}}" />
41+
DockPanel.Dock="Right">
42+
<Interaction.Behaviors>
43+
<behaviors:LostFocusUpdateBindingBehavior Text="{Binding NightTemperature, Converter={x:Static converters:DoubleToStringConverter.Instance}}" />
44+
</Interaction.Behaviors>
45+
</TextBox>
3946
</DockPanel>
4047
<Slider
4148
Margin="0,12,0,0"
@@ -66,8 +73,11 @@
6673
<TextBox
6774
MinWidth="24"
6875
HorizontalAlignment="Right"
69-
DockPanel.Dock="Right"
70-
Text="{Binding DayBrightness, Converter={x:Static converters:FractionToPercentageStringConverter.Instance}}" />
76+
DockPanel.Dock="Right">
77+
<Interaction.Behaviors>
78+
<behaviors:LostFocusUpdateBindingBehavior Text="{Binding DayBrightness, Converter={x:Static converters:FractionToPercentageStringConverter.Instance}}" />
79+
</Interaction.Behaviors>
80+
</TextBox>
7181
</DockPanel>
7282
<Slider
7383
Margin="0,12,0,0"
@@ -98,8 +108,11 @@
98108
<TextBox
99109
MinWidth="24"
100110
HorizontalAlignment="Right"
101-
DockPanel.Dock="Right"
102-
Text="{Binding NightBrightness, Converter={x:Static converters:FractionToPercentageStringConverter.Instance}}" />
111+
DockPanel.Dock="Right">
112+
<Interaction.Behaviors>
113+
<behaviors:LostFocusUpdateBindingBehavior Text="{Binding NightBrightness, Converter={x:Static converters:FractionToPercentageStringConverter.Instance}}" />
114+
</Interaction.Behaviors>
115+
</TextBox>
103116
</DockPanel>
104117
<Slider
105118
Margin="0,12,0,0"
@@ -117,8 +130,11 @@
117130
<TextBox
118131
MinWidth="48"
119132
HorizontalAlignment="Right"
120-
DockPanel.Dock="Right"
121-
Text="{Binding ConfigurationTransitionDuration, Converter={x:Static converters:TimeSpanToDurationStringConverter.Instance}}" />
133+
DockPanel.Dock="Right">
134+
<Interaction.Behaviors>
135+
<behaviors:LostFocusUpdateBindingBehavior Text="{Binding ConfigurationTransitionDuration, Converter={x:Static converters:TimeSpanToDurationStringConverter.Instance}}" />
136+
</Interaction.Behaviors>
137+
</TextBox>
122138
</DockPanel>
123139
<Slider
124140
Margin="0,12,0,0"
@@ -134,8 +150,11 @@
134150
<TextBox
135151
MinWidth="24"
136152
HorizontalAlignment="Right"
137-
DockPanel.Dock="Right"
138-
Text="{Binding ConfigurationTransitionOffset, Converter={x:Static converters:FractionToPercentageStringConverter.Instance}}" />
153+
DockPanel.Dock="Right">
154+
<Interaction.Behaviors>
155+
<behaviors:LostFocusUpdateBindingBehavior Text="{Binding ConfigurationTransitionOffset, Converter={x:Static converters:FractionToPercentageStringConverter.Instance}}" />
156+
</Interaction.Behaviors>
157+
</TextBox>
139158
</DockPanel>
140159
<Slider
141160
Margin="0,12,0,0"

LightBulb/Views/Components/Settings/LocationSettingsTabView.axaml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
x:Class="LightBulb.Views.Components.Settings.LocationSettingsTabView"
33
xmlns="https://github.com/avaloniaui"
44
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5+
xmlns:behaviors="clr-namespace:LightBulb.Behaviors"
56
xmlns:converters="clr-namespace:LightBulb.Converters"
67
xmlns:materialIcons="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
78
xmlns:settings="clr-namespace:LightBulb.ViewModels.Components.Settings">
@@ -37,8 +38,11 @@
3738
<TextBox
3839
MinWidth="24"
3940
HorizontalAlignment="Right"
40-
DockPanel.Dock="Right"
41-
Text="{Binding ManualSunrise, Converter={x:Static converters:TimeOnlyToStringConverter.Instance}}" />
41+
DockPanel.Dock="Right">
42+
<Interaction.Behaviors>
43+
<behaviors:LostFocusUpdateBindingBehavior Text="{Binding ManualSunrise, Converter={x:Static converters:TimeOnlyToStringConverter.Instance}}" />
44+
</Interaction.Behaviors>
45+
</TextBox>
4246
</DockPanel>
4347
<Slider
4448
Margin="0,12,0,0"
@@ -54,8 +58,11 @@
5458
<TextBox
5559
MinWidth="24"
5660
HorizontalAlignment="Right"
57-
DockPanel.Dock="Right"
58-
Text="{Binding ManualSunset, Converter={x:Static converters:TimeOnlyToStringConverter.Instance}}" />
61+
DockPanel.Dock="Right">
62+
<Interaction.Behaviors>
63+
<behaviors:LostFocusUpdateBindingBehavior Text="{Binding ManualSunset, Converter={x:Static converters:TimeOnlyToStringConverter.Instance}}" />
64+
</Interaction.Behaviors>
65+
</TextBox>
5966
</DockPanel>
6067
<Slider
6168
Margin="0,12,0,0"

0 commit comments

Comments
 (0)