Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: elmish/Elmish.WPF
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 27a1294917ef9ab24059c521b1b2144253376151
Choose a base ref
..
head repository: elmish/Elmish.WPF
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 431bcb41eb7c1149abaffd20b918990c06ffcff4
Choose a head ref
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -254,7 +254,24 @@ Then use the following attributes wherever you need a design-time VM:

When targeting .NET Framework, “Project code” must be enabled in the XAML designer for this to work.

When targeting .NET Core 3, a bug in the XAML designer causes design-time data to not be displayed through `DataContext` bindings. See [this issue](https://developercommunity.visualstudio.com/content/problem/1133390/design-time-data-in-datacontext-binding-not-displa.html) for more details.
##### .NET Core 3 workaround

When targeting .NET Core 3, a bug in the XAML designer causes design-time data to not be displayed through `DataContext` bindings. See [this issue](https://developercommunity.visualstudio.com/content/problem/1133390/design-time-data-in-datacontext-binding-not-displa.html) for details. One workaround is to add a `d:DataContext` binding alongside your `DataContext` binding. Change from this:

```xaml
<local:MyControl DataContext="{Binding Child}" />
```

To this:

```xaml
<local:MyControl
DataContext="{Binding Child}"
d:DataContext="{Binding DataContext.Child,
RelativeSource={RelativeSource AncestorType=T}}" />
```

Where `T` is the type of the parent object that contains `local:MyControl` (or a more distant ancestor, though there are issues with using `Window` as the type).

#### Can I open new windows/dialogs?

9 changes: 2 additions & 7 deletions src/Elmish.WPF.Tests/Elmish.WPF.Tests.fsproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">

<PropertyGroup>
<TargetFrameworks>netcoreapp3.0;net461</TargetFrameworks>
<UseWpf>true</UseWpf>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<!--Turn on warnings for unused values (arguments and let bindings) -->
<OtherFlags>$(OtherFlags) --warnon:1182</OtherFlags>
@@ -32,10 +33,4 @@
<ProjectReference Include="..\Elmish.WPF\Elmish.WPF.fsproj" />
</ItemGroup>

<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="WindowsBase" />
</ItemGroup>

</Project>
56 changes: 0 additions & 56 deletions src/Elmish.WPF/ViewModel.fs
Original file line number Diff line number Diff line change
@@ -13,62 +13,6 @@ open Elmish
[<AutoOpen>]
module internal ViewModelHelpers =

let historicalMerge
logInvalidGetSourceId
logInvalidGetTargetId
getSourceId
getTargetId
create
update
(target: ObservableCollection<_>)
(source: _ array) =
let sourceIdxItemPairsById = Dictionary<_,_>(source.Length)
for (idx, s) in source |> Seq.indexed do
let id = getSourceId s
if sourceIdxItemPairsById.ContainsKey id
then logInvalidGetSourceId id (sourceIdxItemPairsById.[id]) s
else sourceIdxItemPairsById.Add(id, (idx, s))

let targetIdxItemPairsById = Dictionary<_,_>(target.Count)
for (idx, t) in target |> Seq.indexed do
let id = getTargetId t
if targetIdxItemPairsById.ContainsKey id
then logInvalidGetTargetId id (targetIdxItemPairsById.[id]) t
else targetIdxItemPairsById.Add(id, (idx, t))

if sourceIdxItemPairsById.Count = source.Length && targetIdxItemPairsById.Count = target.Count then
// Update target items
for Kvp (tId, (tIdx, t)) in targetIdxItemPairsById do
match sourceIdxItemPairsById.TryGetValue tId with
| true, (_, s) -> update t s tIdx
| _ -> ()

// Remove target items that no longer exist
if target.Count <> 0 && source.Length = 0
then target.Clear ()
else
for tIdx in target.Count - 1..-1..0 do
let tId = getTargetId target.[tIdx]
if tId |> sourceIdxItemPairsById.ContainsKey |> not then
let (tIdx2, _) = targetIdxItemPairsById.[tId] // tIdx = tIdx2, so this line is unnecessary
target.RemoveAt tIdx2

// Add target items that don't currently exist
let create (Kvp (sId, (_, s))) = create s sId
sourceIdxItemPairsById
|> Seq.filter (Kvp.key >> targetIdxItemPairsById.ContainsKey >> not)
|> Seq.map create
|> Seq.iter target.Add

// Reorder according to source items
for Kvp (sId, (sIdx, _)) in sourceIdxItemPairsById do
let tIdx =
target
|> Seq.indexed
|> Seq.find (fun (_, t) -> sId = getTargetId t)
|> fst
if tIdx <> sIdx then target.Move(tIdx, sIdx)

let elmStyleMerge
getSourceId
getTargetId
4 changes: 2 additions & 2 deletions src/Samples/SubModel.Views/CounterWithClock.xaml
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
mc:Ignorable="d"
d:DataContext="{x:Static vm:Program.counterWithClockDesignVm}">
<StackPanel>
<local:Counter DataContext="{Binding Counter}" HorizontalAlignment="Center" />
<local:Clock DataContext="{Binding Clock}" HorizontalAlignment="Center" />
<local:Counter DataContext="{Binding Counter}" d:DataContext="{Binding DataContext.Counter, RelativeSource={RelativeSource AncestorType=UserControl}}" HorizontalAlignment="Center" />
<local:Clock DataContext="{Binding Clock}" d:DataContext="{Binding DataContext.Clock, RelativeSource={RelativeSource AncestorType=UserControl}}" HorizontalAlignment="Center" />
</StackPanel>
</UserControl>
4 changes: 2 additions & 2 deletions src/Samples/SubModel.Views/MainWindow.xaml
Original file line number Diff line number Diff line change
@@ -13,8 +13,8 @@
d:DataContext="{x:Static vm:Program.mainDesignVm}">
<StackPanel>
<TextBlock Text="Counter with clock 1" FontSize="18" FontWeight="Bold" Margin="0,25,0,0" HorizontalAlignment="Center" />
<local:CounterWithClock DataContext="{Binding ClockCounter1}" />
<local:CounterWithClock DataContext="{Binding ClockCounter1}" d:DataContext="{Binding DataContext.ClockCounter1, RelativeSource={RelativeSource AncestorType=StackPanel}}"/>
<TextBlock Text="Counter with clock 2" FontSize="18" FontWeight="Bold" Margin="0,25,0,0" HorizontalAlignment="Center" />
<local:CounterWithClock DataContext="{Binding ClockCounter2}" />
<local:CounterWithClock DataContext="{Binding ClockCounter2}" d:DataContext="{Binding DataContext.ClockCounter2, RelativeSource={RelativeSource AncestorType=StackPanel}}"/>
</StackPanel>
</Window>
6 changes: 4 additions & 2 deletions src/Samples/SubModelOpt.Views/MainWindow.xaml
Original file line number Diff line number Diff line change
@@ -34,13 +34,15 @@
<StackPanel Background="White">
<local:Form1
DataContext="{Binding Form1}"
d:DataContext="{Binding DataContext.Form1, RelativeSource={RelativeSource AncestorType=StackPanel}}"
Visibility="{Binding DataContext.Form1Visible,
RelativeSource={RelativeSource AncestorType=Window},
RelativeSource={RelativeSource AncestorType=StackPanel},
Converter={StaticResource VisibilityConverter}}" />
<local:Form2
DataContext="{Binding Form2}"
d:DataContext="{Binding DataContext.Form2, RelativeSource={RelativeSource AncestorType=StackPanel}}"
Visibility="{Binding DataContext.Form2Visible,
RelativeSource={RelativeSource AncestorType=Window},
RelativeSource={RelativeSource AncestorType=StackPanel},
Converter={StaticResource VisibilityConverter}}" />
</StackPanel>
</Border>