`ILockedFrameBuffer.Dpi` was a `Size` but it would make more sense as a `Vector` because `Size * Vector` produces a `Size` whereas a `Size * Size` would produce a `Size3D` if that type existed.
- Showing a window was causing it to be added to the collection twice because `Show()` called `IsVisible = true` which called `Show()`
- The window wasn't getting removed when the `PlatformImpl` signalled it was closed
They were not correct before. Also clarified the two types of
conversions:
- `TryConvertImplicit` implements the implicit conversions allowed by
the C# language
- `TryConvert` tries every means at its disposal to convert a value to a
type
`AvaloniaObject` uses only implicit conversions. This allows one to
write:
```
var control = new TextBlock
{
[Canvas.TopProperty] = 10
}
```
Without implicit conversions, this would fail because `Canvas.Top` is a
`double` whereas `10` is an `int`, however only implicit conversions
should be used here, otherwise the following would pass, which is
probably not what would be wanted:
```
var control = new TextBlock
{
[TextBlock.TextProperty] = observable, // Text is now the type name of
`observable`
}
```
`DefaultValueConverter` uses `TryConvert`, i.e. every conversion
possible.
Fixes#972.
`IRenderer` mock was keeping hold of references passed to `AddDirty` -
tried resetting the mock but references were still held, so replaced the
mock `IRenderer` with a `NullRenderer` that fixes the problem.
Make `SolidColorBrush` immutable, but make the static `Brushes`
properties return immutable brushes. The immutable brushes will be
needed by the deferred renderer.