Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit 8e14765

Browse files
committed
Fix all the bindings
A bunch of classes were doing xaml bindings in a very wrong way, relying on some external code setting the ViewModel property explicitly and not defining the bindings in xaml. Make every SimpleUserControl subclass set the ViewModel property via the DataContextChanged event (DataContext is set for every view in UIController), and fix the xaml bindings so things work. Remove useless ReactiveUI code-behind bindings while we're at it, it's pointless doing it twice. This should fix #274 and #275
1 parent e482125 commit 8e14765

20 files changed

+421
-447
lines changed

src/GitHub.App/SampleData/SampleViewModels.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,20 @@ public RepositoryCreationViewModelDesigner()
4040
RepositoryName = "Hello-World";
4141
Description = "A description";
4242
KeepPrivate = true;
43+
CanKeepPrivate = true;
4344
Accounts = new ReactiveList<IAccount>
4445
{
4546
new AccountDesigner { Login = "shana" },
4647
new AccountDesigner { Login = "GitHub", IsUser = false }
4748
};
49+
SelectedAccount = Accounts[0];
4850
GitIgnoreTemplates = new ReactiveList<GitIgnoreItem>
4951
{
5052
GitIgnoreItem.Create("VisualStudio"),
5153
GitIgnoreItem.Create("Wap"),
5254
GitIgnoreItem.Create("WordPress")
5355
};
54-
56+
SelectedGitIgnoreTemplate = GitIgnoreTemplates[0];
5557
Licenses = new ReactiveList<LicenseItem>
5658
{
5759
new LicenseItem("agpl-3.0", "GNU Affero GPL v3.0"),
@@ -60,16 +62,15 @@ public RepositoryCreationViewModelDesigner()
6062
new LicenseItem("mit", "MIT License")
6163
};
6264

63-
SelectedLicense = LicenseItem.None;
64-
SelectedGitIgnoreTemplate = null;
65+
SelectedLicense = Licenses[0];
6566
}
6667

6768
public new string Title { get { return "Create a GitHub Repository"; } } // TODO: this needs to be contextual
6869

6970
public IReadOnlyList<IAccount> Accounts
7071
{
7172
get;
72-
private set;
73+
set;
7374
}
7475

7576
public string BaseRepositoryPath
@@ -223,7 +224,7 @@ public void Dispose()
223224

224225
public RepositoryPublishViewModelDesigner()
225226
{
226-
Connections = new ReactiveList<IConnection>
227+
Connections = new ObservableCollection<IConnection>
227228
{
228229
new Conn() { HostAddress = new HostAddress() },
229230
new Conn() { HostAddress = HostAddress.Create("ghe.io") }
@@ -259,7 +260,7 @@ public IReactiveCommand<ProgressState> PublishRepository
259260
private set;
260261
}
261262

262-
public ReactiveList<IConnection> Connections
263+
public ObservableCollection<IConnection> Connections
263264
{
264265
get;
265266
private set;

src/GitHub.App/ViewModels/RepositoryPublishViewModel.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public RepositoryPublishViewModel(
5252
)
5353
.ToProperty(this, x => x.Title);
5454

55-
Connections = new ReactiveList<IConnection>(connectionManager.Connections);
55+
Connections = connectionManager.Connections;
5656
this.repositoryPublishService = repositoryPublishService;
5757

5858
if (Connections.Any())
@@ -112,7 +112,7 @@ public RepositoryPublishViewModel(
112112
public bool IsPublishing { get { return isPublishing.Value; } }
113113

114114
public IReactiveCommand<ProgressState> PublishRepository { get; private set; }
115-
public ReactiveList<IConnection> Connections { get; private set; }
115+
public ObservableCollection<IConnection> Connections { get; private set; }
116116

117117
IConnection selectedConnection;
118118
[AllowNull]

src/GitHub.Exports.Reactive/ViewModels/IRepositoryPublishViewModel.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
using System.Reactive;
22
using GitHub.Models;
33
using ReactiveUI;
4+
using System.Collections.ObjectModel;
45

56
namespace GitHub.ViewModels
67
{
78
public interface IRepositoryPublishViewModel : IRepositoryForm
89
{
9-
ReactiveList<IConnection> Connections { get; }
10+
ObservableCollection<IConnection> Connections { get; }
1011

1112
/// <summary>
1213
/// Command that creates the repository.

src/GitHub.TeamFoundation.14/Sync/GitHubPublishSection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using GitHub.VisualStudio.TeamExplorer;
1616
using System.Windows.Controls;
1717
using GitHub.VisualStudio.UI;
18+
using GitHub.ViewModels;
1819

1920
namespace GitHub.VisualStudio.TeamExplorer.Sync
2021
{
@@ -126,7 +127,6 @@ void ShowPublish()
126127
{
127128
var c = data.View;
128129
SectionContent = c;
129-
((UserControl)c).DataContext = this;
130130
c.IsBusy.Subscribe(x => IsBusy = x);
131131
},
132132
() =>

src/GitHub.UI.Reactive/Controls/SimpleViewUserControl.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,19 +88,24 @@ public void Dispose()
8888
}
8989
}
9090

91-
public class SimpleViewUserControl<TViewModel, TImplementor> : SimpleViewUserControl, IViewFor<TViewModel>, IView
92-
where TViewModel : class, IViewModel
91+
public class SimpleViewUserControl<TInterface, TImplementor> : SimpleViewUserControl, IViewFor<TInterface>, IView
92+
where TInterface : class, IViewModel
9393
where TImplementor : class
9494
{
95+
public SimpleViewUserControl()
96+
{
97+
DataContextChanged += (s, e) => ViewModel = (TInterface)e.NewValue;
98+
}
99+
95100
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(
96-
"ViewModel", typeof(TViewModel), typeof(TImplementor), new PropertyMetadata(null));
101+
"ViewModel", typeof(TInterface), typeof(TImplementor), new PropertyMetadata(null));
97102

98103
[AllowNull]
99104
object IViewFor.ViewModel
100105
{
101106
[return:AllowNull]
102107
get { return ViewModel; }
103-
set { ViewModel = (TViewModel)value; }
108+
set { ViewModel = (TInterface)value; }
104109
}
105110

106111
[AllowNull]
@@ -111,15 +116,15 @@ IViewModel IView.ViewModel
111116
}
112117

113118
[AllowNull]
114-
public TViewModel ViewModel
119+
public TInterface ViewModel
115120
{
116121
[return: AllowNull]
117-
get { return (TViewModel)GetValue(ViewModelProperty); }
122+
get { return (TInterface)GetValue(ViewModelProperty); }
118123
set { SetValue(ViewModelProperty, value); }
119124
}
120125

121126
[AllowNull]
122-
TViewModel IViewFor<TViewModel>.ViewModel
127+
TInterface IViewFor<TInterface>.ViewModel
123128
{
124129
[return: AllowNull]
125130
get { return ViewModel; }

src/GitHub.VisualStudio/Converters/CountToVisibilityConverter.cs renamed to src/GitHub.UI/Converters/CountToVisibilityConverter.cs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,18 @@
44
using System.Windows.Data;
55
using NullGuard;
66

7-
namespace GitHub.VisualStudio.Converters
7+
namespace GitHub.UI
88
{
99
/// <summary>
1010
/// Convert a count to visibility based on the following rule:
1111
/// * If count == 0, return Visibility.Visible
1212
/// * If count > 0, return Visibility.Collapsed
1313
/// </summary>
14-
public class CountToVisibilityConverter : IValueConverter
14+
public class CountToVisibilityConverter : ValueConverterMarkupExtension<CountToVisibilityConverter>
1515
{
16-
public object Convert(object value, Type targetType, [AllowNull] object parameter, [AllowNull] CultureInfo culture)
16+
public override object Convert(object value, Type targetType, [AllowNull] object parameter, [AllowNull] CultureInfo culture)
1717
{
1818
return ((int)value == 0) ? Visibility.Visible : Visibility.Collapsed;
1919
}
20-
21-
[return: AllowNull]
22-
public object ConvertBack(object value, Type targetType, [AllowNull] object parameter, [AllowNull] CultureInfo culture)
23-
{
24-
return null;
25-
}
2620
}
2721
}

src/GitHub.UI/GitHub.UI.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
<DesignTime>True</DesignTime>
8686
<DependentUpon>OcticonPaths.resx</DependentUpon>
8787
</Compile>
88+
<Compile Include="Converters\CountToVisibilityConverter.cs" />
8889
<Compile Include="Converters\DefaultValueConverter.cs" />
8990
<Compile Include="Converters\StickieListItemConverter.cs" />
9091
<Compile Include="Resources.Designer.cs">

src/GitHub.VisualStudio/GitHub.VisualStudio.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,6 @@
204204
<Link>Properties\SolutionInfo.cs</Link>
205205
</Compile>
206206
<Compile Include="Base\MenuBase.cs" />
207-
<Compile Include="Converters\CountToVisibilityConverter.cs" />
208207
<Compile Include="..\common\SharedDictionaryManager.cs">
209208
<Link>Helpers\SharedDictionaryManager.cs</Link>
210209
</Compile>

src/GitHub.VisualStudio/UI/Views/Controls/LoginControl.xaml.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ public LoginControl()
2626
{
2727
InitializeComponent();
2828

29-
DataContextChanged += (s, e) => ViewModel = (ILoginControlViewModel)e.NewValue;
30-
3129
this.WhenActivated(d =>
3230
{
3331
SetupDotComBindings(d);

src/GitHub.VisualStudio/UI/Views/Controls/RepositoryCloneControl.xaml.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ public RepositoryCloneControl()
3434
{
3535
InitializeComponent();
3636

37-
DataContextChanged += (s, e) => ViewModel = e.NewValue as IRepositoryCloneViewModel;
38-
3937
this.WhenActivated(d =>
4038
{
4139
d(this.OneWayBind(ViewModel, vm => vm.IsLoading, v => v.loadingProgressBar.Visibility));

0 commit comments

Comments
 (0)