diff --git a/samples/ControlCatalog.NetCore/Program.cs b/samples/ControlCatalog.NetCore/Program.cs index 854cae484c..2a5294cacc 100644 --- a/samples/ControlCatalog.NetCore/Program.cs +++ b/samples/ControlCatalog.NetCore/Program.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; @@ -6,6 +7,7 @@ using System.Threading; using Avalonia; using Avalonia.ReactiveUI; using Avalonia.Dialogs; +using Avalonia.OpenGL; namespace ControlCatalog.NetCore { diff --git a/samples/ControlCatalog/ControlCatalog.csproj b/samples/ControlCatalog/ControlCatalog.csproj index 11c0a4fa68..34a6e33677 100644 --- a/samples/ControlCatalog/ControlCatalog.csproj +++ b/samples/ControlCatalog/ControlCatalog.csproj @@ -1,6 +1,7 @@  - netstandard2.0 + netstandard2.0 + true @@ -17,6 +18,7 @@ + diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml index e02308b5c6..30671ef083 100644 --- a/samples/ControlCatalog/MainView.xaml +++ b/samples/ControlCatalog/MainView.xaml @@ -47,6 +47,7 @@ + diff --git a/samples/ControlCatalog/Pages/OpenGlPage.xaml b/samples/ControlCatalog/Pages/OpenGlPage.xaml new file mode 100644 index 0000000000..0eb09004ba --- /dev/null +++ b/samples/ControlCatalog/Pages/OpenGlPage.xaml @@ -0,0 +1,29 @@ + + + + + + + + + Yaw + + Pitch + + Roll + + + D + I + S + C + O + + + + + + diff --git a/samples/ControlCatalog/Pages/OpenGlPage.xaml.cs b/samples/ControlCatalog/Pages/OpenGlPage.xaml.cs new file mode 100644 index 0000000000..6c13a5ac22 --- /dev/null +++ b/samples/ControlCatalog/Pages/OpenGlPage.xaml.cs @@ -0,0 +1,401 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Numerics; +using System.Runtime.InteropServices; +using Avalonia; +using Avalonia.Controls; +using Avalonia.OpenGL; +using Avalonia.Platform.Interop; +using Avalonia.Threading; +using static Avalonia.OpenGL.GlConsts; +// ReSharper disable StringLiteralTypo + +namespace ControlCatalog.Pages +{ + public class OpenGlPage : UserControl + { + + } + + public class OpenGlPageControl : OpenGlControlBase + { + private float _yaw; + + public static readonly DirectProperty YawProperty = + AvaloniaProperty.RegisterDirect("Yaw", o => o.Yaw, (o, v) => o.Yaw = v); + + public float Yaw + { + get => _yaw; + set => SetAndRaise(YawProperty, ref _yaw, value); + } + + private float _pitch; + + public static readonly DirectProperty PitchProperty = + AvaloniaProperty.RegisterDirect("Pitch", o => o.Pitch, (o, v) => o.Pitch = v); + + public float Pitch + { + get => _pitch; + set => SetAndRaise(PitchProperty, ref _pitch, value); + } + + + private float _roll; + + public static readonly DirectProperty RollProperty = + AvaloniaProperty.RegisterDirect("Roll", o => o.Roll, (o, v) => o.Roll = v); + + public float Roll + { + get => _roll; + set => SetAndRaise(RollProperty, ref _roll, value); + } + + + private float _disco; + + public static readonly DirectProperty DiscoProperty = + AvaloniaProperty.RegisterDirect("Disco", o => o.Disco, (o, v) => o.Disco = v); + + public float Disco + { + get => _disco; + set => SetAndRaise(DiscoProperty, ref _disco, value); + } + + private string _info; + + public static readonly DirectProperty InfoProperty = + AvaloniaProperty.RegisterDirect("Info", o => o.Info, (o, v) => o.Info = v); + + public string Info + { + get => _info; + private set => SetAndRaise(InfoProperty, ref _info, value); + } + + static OpenGlPageControl() + { + AffectsRender(YawProperty, PitchProperty, RollProperty, DiscoProperty); + } + + private int _vertexShader; + private int _fragmentShader; + private int _shaderProgram; + private int _vertexBufferObject; + private int _indexBufferObject; + private int _vertexArrayObject; + private GlExtrasInterface _glExt; + + private string GetShader(bool fragment, string shader) + { + var version = (GlVersion.Type == GlProfileType.OpenGL ? + RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? 150 : 120 : + 100); + var data = "#version " + version + "\n"; + if (GlVersion.Type == GlProfileType.OpenGLES) + data += "precision mediump float;\n"; + if (version >= 150) + { + shader = shader.Replace("attribute", "in"); + if (fragment) + shader = shader + .Replace("varying", "in") + .Replace("//DECLAREGLFRAG", "out vec4 outFragColor;") + .Replace("gl_FragColor", "outFragColor"); + else + shader = shader.Replace("varying", "out"); + } + + data += shader; + + return data; + } + + + private string VertexShaderSource => GetShader(false, @" + attribute vec3 aPos; + attribute vec3 aNormal; + uniform mat4 uModel; + uniform mat4 uProjection; + uniform mat4 uView; + + varying vec3 FragPos; + varying vec3 VecPos; + varying vec3 Normal; + uniform float uTime; + uniform float uDisco; + void main() + { + float discoScale = sin(uTime * 10.0) / 10.0; + float distortionX = 1.0 + uDisco * cos(uTime * 20.0) / 10.0; + + float scale = 1.0 + uDisco * discoScale; + + vec3 scaledPos = aPos; + scaledPos.x = scaledPos.x * distortionX; + + scaledPos *= scale; + gl_Position = uProjection * uView * uModel * vec4(scaledPos, 1.0); + FragPos = vec3(uModel * vec4(aPos, 1.0)); + VecPos = aPos; + Normal = normalize(vec3(uModel * vec4(aNormal, 1.0))); + } +"); + + private string FragmentShaderSource => GetShader(true, @" + varying vec3 FragPos; + varying vec3 VecPos; + varying vec3 Normal; + uniform float uMaxY; + uniform float uMinY; + uniform float uTime; + uniform float uDisco; + //DECLAREGLFRAG + + void main() + { + float y = (VecPos.y - uMinY) / (uMaxY - uMinY); + float c = cos(atan(VecPos.x, VecPos.z) * 20.0 + uTime * 40.0 + y * 50.0); + float s = sin(-atan(VecPos.z, VecPos.x) * 20.0 - uTime * 20.0 - y * 30.0); + + vec3 discoColor = vec3( + 0.5 + abs(0.5 - y) * cos(uTime * 10.0), + 0.25 + (smoothstep(0.3, 0.8, y) * (0.5 - c / 4.0)), + 0.25 + abs((smoothstep(0.1, 0.4, y) * (0.5 - s / 4.0)))); + + vec3 objectColor = vec3((1.0 - y), 0.40 + y / 4.0, y * 0.75 + 0.25); + objectColor = objectColor * (1.0 - uDisco) + discoColor * uDisco; + + float ambientStrength = 0.3; + vec3 lightColor = vec3(1.0, 1.0, 1.0); + vec3 lightPos = vec3(uMaxY * 2.0, uMaxY * 2.0, uMaxY * 2.0); + vec3 ambient = ambientStrength * lightColor; + + + vec3 norm = normalize(Normal); + vec3 lightDir = normalize(lightPos - FragPos); + + float diff = max(dot(norm, lightDir), 0.0); + vec3 diffuse = diff * lightColor; + + vec3 result = (ambient + diffuse) * objectColor; + gl_FragColor = vec4(result, 1.0); + + } +"); + + [StructLayout(LayoutKind.Sequential, Pack = 4)] + private struct Vertex + { + public Vector3 Position; + public Vector3 Normal; + } + + private readonly Vertex[] _points; + private readonly ushort[] _indices; + private readonly float _minY; + private readonly float _maxY; + + + public OpenGlPageControl() + { + var name = typeof(OpenGlPage).Assembly.GetManifestResourceNames().First(x => x.Contains("teapot.bin")); + using (var sr = new BinaryReader(typeof(OpenGlPage).Assembly.GetManifestResourceStream(name))) + { + var buf = new byte[sr.ReadInt32()]; + sr.Read(buf, 0, buf.Length); + var points = new float[buf.Length / 4]; + Buffer.BlockCopy(buf, 0, points, 0, buf.Length); + buf = new byte[sr.ReadInt32()]; + sr.Read(buf, 0, buf.Length); + _indices = new ushort[buf.Length / 2]; + Buffer.BlockCopy(buf, 0, _indices, 0, buf.Length); + _points = new Vertex[points.Length / 3]; + for (var primitive = 0; primitive < points.Length / 3; primitive++) + { + var srci = primitive * 3; + _points[primitive] = new Vertex + { + Position = new Vector3(points[srci], points[srci + 1], points[srci + 2]) + }; + } + + for (int i = 0; i < _indices.Length; i += 3) + { + Vector3 a = _points[_indices[i]].Position; + Vector3 b = _points[_indices[i + 1]].Position; + Vector3 c = _points[_indices[i + 2]].Position; + var normal = Vector3.Normalize(Vector3.Cross(c - b, a - b)); + + _points[_indices[i]].Normal += normal; + _points[_indices[i + 1]].Normal += normal; + _points[_indices[i + 2]].Normal += normal; + } + + for (int i = 0; i < _points.Length; i++) + { + _points[i].Normal = Vector3.Normalize(_points[i].Normal); + _maxY = Math.Max(_maxY, _points[i].Position.Y); + _minY = Math.Min(_minY, _points[i].Position.Y); + } + } + + } + + private void CheckError(GlInterface gl) + { + int err; + while ((err = gl.GetError()) != GL_NO_ERROR) + Console.WriteLine(err); + } + + protected unsafe override void OnOpenGlInit(GlInterface GL, int fb) + { + CheckError(GL); + _glExt = new GlExtrasInterface(GL); + + Info = $"Renderer: {GL.GetString(GL_RENDERER)} Version: {GL.GetString(GL_VERSION)}"; + + // Load the source of the vertex shader and compile it. + _vertexShader = GL.CreateShader(GL_VERTEX_SHADER); + Console.WriteLine(GL.CompileShaderAndGetError(_vertexShader, VertexShaderSource)); + + // Load the source of the fragment shader and compile it. + _fragmentShader = GL.CreateShader(GL_FRAGMENT_SHADER); + Console.WriteLine(GL.CompileShaderAndGetError(_fragmentShader, FragmentShaderSource)); + + // Create the shader program, attach the vertex and fragment shaders and link the program. + _shaderProgram = GL.CreateProgram(); + GL.AttachShader(_shaderProgram, _vertexShader); + GL.AttachShader(_shaderProgram, _fragmentShader); + const int positionLocation = 0; + const int normalLocation = 1; + GL.BindAttribLocationString(_shaderProgram, positionLocation, "aPos"); + GL.BindAttribLocationString(_shaderProgram, normalLocation, "aNormal"); + Console.WriteLine(GL.LinkProgramAndGetError(_shaderProgram)); + CheckError(GL); + + // Create the vertex buffer object (VBO) for the vertex data. + _vertexBufferObject = GL.GenBuffer(); + // Bind the VBO and copy the vertex data into it. + GL.BindBuffer(GL_ARRAY_BUFFER, _vertexBufferObject); + CheckError(GL); + var vertexSize = Marshal.SizeOf(); + fixed (void* pdata = _points) + GL.BufferData(GL_ARRAY_BUFFER, new IntPtr(_points.Length * vertexSize), + new IntPtr(pdata), GL_STATIC_DRAW); + + _indexBufferObject = GL.GenBuffer(); + GL.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferObject); + CheckError(GL); + fixed (void* pdata = _indices) + GL.BufferData(GL_ELEMENT_ARRAY_BUFFER, new IntPtr(_indices.Length * sizeof(ushort)), new IntPtr(pdata), + GL_STATIC_DRAW); + CheckError(GL); + _vertexArrayObject = _glExt.GenVertexArray(); + _glExt.BindVertexArray(_vertexArrayObject); + CheckError(GL); + GL.VertexAttribPointer(positionLocation, 3, GL_FLOAT, + 0, vertexSize, IntPtr.Zero); + GL.VertexAttribPointer(normalLocation, 3, GL_FLOAT, + 0, vertexSize, new IntPtr(12)); + GL.EnableVertexAttribArray(positionLocation); + GL.EnableVertexAttribArray(normalLocation); + CheckError(GL); + + } + + protected override void OnOpenGlDeinit(GlInterface GL, int fb) + { + // Unbind everything + GL.BindBuffer(GL_ARRAY_BUFFER, 0); + GL.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + _glExt.BindVertexArray(0); + GL.UseProgram(0); + + // Delete all resources. + GL.DeleteBuffers(2, new[] { _vertexBufferObject, _indexBufferObject }); + _glExt.DeleteVertexArrays(1, new[] { _vertexArrayObject }); + GL.DeleteProgram(_shaderProgram); + GL.DeleteShader(_fragmentShader); + GL.DeleteShader(_vertexShader); + } + + static Stopwatch St = Stopwatch.StartNew(); + protected override unsafe void OnOpenGlRender(GlInterface gl, int fb) + { + gl.ClearColor(0, 0, 0, 0); + gl.Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + gl.Enable(GL_DEPTH_TEST); + gl.Viewport(0, 0, (int)Bounds.Width, (int)Bounds.Height); + var GL = gl; + + GL.BindBuffer(GL_ARRAY_BUFFER, _vertexBufferObject); + GL.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferObject); + _glExt.BindVertexArray(_vertexArrayObject); + GL.UseProgram(_shaderProgram); + CheckError(GL); + var projection = + Matrix4x4.CreatePerspectiveFieldOfView((float)(Math.PI / 4), (float)(Bounds.Width / Bounds.Height), + 0.01f, 1000); + + + var view = Matrix4x4.CreateLookAt(new Vector3(25, 25, 25), new Vector3(), new Vector3(0, -1, 0)); + var model = Matrix4x4.CreateFromYawPitchRoll(_yaw, _pitch, _roll); + var modelLoc = GL.GetUniformLocationString(_shaderProgram, "uModel"); + var viewLoc = GL.GetUniformLocationString(_shaderProgram, "uView"); + var projectionLoc = GL.GetUniformLocationString(_shaderProgram, "uProjection"); + var maxYLoc = GL.GetUniformLocationString(_shaderProgram, "uMaxY"); + var minYLoc = GL.GetUniformLocationString(_shaderProgram, "uMinY"); + var timeLoc = GL.GetUniformLocationString(_shaderProgram, "uTime"); + var discoLoc = GL.GetUniformLocationString(_shaderProgram, "uDisco"); + GL.UniformMatrix4fv(modelLoc, 1, false, &model); + GL.UniformMatrix4fv(viewLoc, 1, false, &view); + GL.UniformMatrix4fv(projectionLoc, 1, false, &projection); + GL.Uniform1f(maxYLoc, _maxY); + GL.Uniform1f(minYLoc, _minY); + GL.Uniform1f(timeLoc, (float)St.Elapsed.TotalSeconds); + GL.Uniform1f(discoLoc, _disco); + CheckError(GL); + GL.DrawElements(GL_TRIANGLES, _indices.Length, GL_UNSIGNED_SHORT, IntPtr.Zero); + + CheckError(GL); + if (_disco > 0.01) + Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background); + } + + class GlExtrasInterface : GlInterfaceBase + { + public GlExtrasInterface(GlInterface gl) : base(gl.GetProcAddress, gl.ContextInfo) + { + } + + public delegate void GlDeleteVertexArrays(int count, int[] buffers); + [GlMinVersionEntryPoint("glDeleteVertexArrays", 3,0)] + [GlExtensionEntryPoint("glDeleteVertexArraysOES", "GL_OES_vertex_array_object")] + public GlDeleteVertexArrays DeleteVertexArrays { get; } + + public delegate void GlBindVertexArray(int array); + [GlMinVersionEntryPoint("glBindVertexArray", 3,0)] + [GlExtensionEntryPoint("glBindVertexArrayOES", "GL_OES_vertex_array_object")] + public GlBindVertexArray BindVertexArray { get; } + public delegate void GlGenVertexArrays(int n, int[] rv); + + [GlMinVersionEntryPoint("glGenVertexArrays",3,0)] + [GlExtensionEntryPoint("glGenVertexArraysOES", "GL_OES_vertex_array_object")] + public GlGenVertexArrays GenVertexArrays { get; } + + public int GenVertexArray() + { + var rv = new int[1]; + GenVertexArrays(1, rv); + return rv[0]; + } + } + } +} diff --git a/samples/ControlCatalog/Pages/teapot.bin b/samples/ControlCatalog/Pages/teapot.bin new file mode 100644 index 0000000000..589eeb912d Binary files /dev/null and b/samples/ControlCatalog/Pages/teapot.bin differ diff --git a/scripts/ReplaceNugetCache.ps1 b/scripts/ReplaceNugetCache.ps1 index 70f5eaa40b..2543e58249 100644 --- a/scripts/ReplaceNugetCache.ps1 +++ b/scripts/ReplaceNugetCache.ps1 @@ -1,5 +1,5 @@ -copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netcoreapp2.0\ -copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netstandard2.0\ -copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp2.0\Avalonia.Win32.dll ~\.nuget\packages\avalonia.win32\$args\lib\netstandard2.0\ -copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp2.0\Avalonia.Skia.dll ~\.nuget\packages\avalonia.skia\$args\lib\netstandard2.0\ -copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp2.0\Avalonia.Skia.dll ~\.nuget\packages\avalonia.direct2d1\$args\lib\netstandard2.0\ +copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp3.1\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netcoreapp2.0\ +copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp3.1\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netstandard2.0\ +copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp3.1\Avalonia.Win32.dll ~\.nuget\packages\avalonia.win32\$args\lib\netstandard2.0\ +copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp3.1\Avalonia.Skia.dll ~\.nuget\packages\avalonia.skia\$args\lib\netstandard2.0\ +copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp3.1\Avalonia.Skia.dll ~\.nuget\packages\avalonia.direct2d1\$args\lib\netstandard2.0\ diff --git a/scripts/ReplaceNugetCacheRelease.ps1 b/scripts/ReplaceNugetCacheRelease.ps1 index 1c19e00400..96678819a4 100644 --- a/scripts/ReplaceNugetCacheRelease.ps1 +++ b/scripts/ReplaceNugetCacheRelease.ps1 @@ -1,5 +1,5 @@ -copy ..\samples\ControlCatalog.NetCore\bin\Release\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netcoreapp2.0\ -copy ..\samples\ControlCatalog.NetCore.\bin\Release\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netstandard2.0\ -copy ..\samples\ControlCatalog.NetCore.\bin\Release\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia.gtk3\$args\lib\netstandard2.0\ -copy ..\samples\ControlCatalog.NetCore.\bin\Release\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia.win32\$args\lib\netstandard2.0\ -copy ..\samples\ControlCatalog.NetCore.\bin\Release\netcoreapp2.0\Avalonia**.dll ~\.nuget\packages\avalonia.skia\$args\lib\netstandard2.0\ \ No newline at end of file +copy ..\samples\ControlCatalog.NetCore\bin\Release\netcoreapp3.1\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netcoreapp2.0\ +copy ..\samples\ControlCatalog.NetCore\bin\Release\netcoreapp3.1\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netstandard2.0\ +copy ..\samples\ControlCatalog.NetCore\bin\Release\netcoreapp3.1\Avalonia.Win32.dll ~\.nuget\packages\avalonia.win32\$args\lib\netstandard2.0\ +copy ..\samples\ControlCatalog.NetCore\bin\Release\netcoreapp3.1\Avalonia.Skia.dll ~\.nuget\packages\avalonia.skia\$args\lib\netstandard2.0\ +copy ..\samples\ControlCatalog.NetCore\bin\Release\netcoreapp3.1\Avalonia.Skia.dll ~\.nuget\packages\avalonia.direct2d1\$args\lib\netstandard2.0\ \ No newline at end of file diff --git a/src/Avalonia.Base/Utilities/DisposableLock.cs b/src/Avalonia.Base/Utilities/DisposableLock.cs new file mode 100644 index 0000000000..b06e97da00 --- /dev/null +++ b/src/Avalonia.Base/Utilities/DisposableLock.cs @@ -0,0 +1,50 @@ +using System; +using System.Threading; + +namespace Avalonia.Utilities +{ + public class DisposableLock + { + private readonly object _lock = new object(); + + /// + /// Tries to take a lock + /// + /// IDisposable if succeeded to obtain the lock + public IDisposable TryLock() + { + if (Monitor.TryEnter(_lock)) + return new UnlockDisposable(_lock); + return null; + } + + /// + /// Enters a waiting lock + /// + public IDisposable Lock() + { + Monitor.Enter(_lock); + return new UnlockDisposable(_lock); + } + + private sealed class UnlockDisposable : IDisposable + { + private object _lock; + + public UnlockDisposable(object @lock) + { + _lock = @lock; + } + + public void Dispose() + { + object @lock = Interlocked.Exchange(ref _lock, null); + + if (@lock != null) + { + Monitor.Exit(@lock); + } + } + } + } +} diff --git a/src/Avalonia.Controls.DataGrid/DataGrid.cs b/src/Avalonia.Controls.DataGrid/DataGrid.cs index 844316741a..3a1e612a05 100644 --- a/src/Avalonia.Controls.DataGrid/DataGrid.cs +++ b/src/Avalonia.Controls.DataGrid/DataGrid.cs @@ -2245,7 +2245,7 @@ namespace Avalonia.Controls /// Builds the visual tree for the column header when a new template is applied. /// //TODO Validation UI - protected override void OnTemplateApplied(TemplateAppliedEventArgs e) + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { // The template has changed, so we need to refresh the visuals _measured = false; diff --git a/src/Avalonia.Controls.DataGrid/DataGridCell.cs b/src/Avalonia.Controls.DataGrid/DataGridCell.cs index 98d27b72bc..3973f1e86f 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridCell.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridCell.cs @@ -121,10 +121,8 @@ namespace Avalonia.Controls /// /// Builds the visual tree for the cell control when a new template is applied. /// - protected override void OnTemplateApplied(TemplateAppliedEventArgs e) + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { - base.OnTemplateApplied(e); - UpdatePseudoClasses(); _rightGridLine = e.NameScope.Find(DATAGRIDCELL_elementRightGridLine); if (_rightGridLine != null && OwningColumn == null) diff --git a/src/Avalonia.Controls.DataGrid/DataGridRow.cs b/src/Avalonia.Controls.DataGrid/DataGridRow.cs index 15374567db..df200240ff 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridRow.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridRow.cs @@ -536,10 +536,8 @@ namespace Avalonia.Controls /// /// Builds the visual tree for the column header when a new template is applied. /// - protected override void OnTemplateApplied(TemplateAppliedEventArgs e) + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { - base.OnTemplateApplied(e); - RootElement = e.NameScope.Find(DATAGRIDROW_elementRoot); if (RootElement != null) { diff --git a/src/Avalonia.Controls.DataGrid/DataGridRowGroupHeader.cs b/src/Avalonia.Controls.DataGrid/DataGridRowGroupHeader.cs index 513b7f55e2..0790fcf5d5 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridRowGroupHeader.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridRowGroupHeader.cs @@ -168,7 +168,7 @@ namespace Avalonia.Controls private IDisposable _expanderButtonSubscription; - protected override void OnTemplateApplied(TemplateAppliedEventArgs e) + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { _rootElement = e.NameScope.Find(DataGridRow.DATAGRIDROW_elementRoot); @@ -199,8 +199,6 @@ namespace Avalonia.Controls _itemCountElement = e.NameScope.Find(DATAGRIDROWGROUPHEADER_itemCountElement); _propertyNameElement = e.NameScope.Find(DATAGRIDROWGROUPHEADER_propertyNameElement); UpdateTitleElements(); - - base.OnTemplateApplied(e); } internal void ApplyHeaderStatus() diff --git a/src/Avalonia.Controls.DataGrid/DataGridRowHeader.cs b/src/Avalonia.Controls.DataGrid/DataGridRowHeader.cs index 3c1a4603c9..324227d749 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridRowHeader.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridRowHeader.cs @@ -94,10 +94,8 @@ namespace Avalonia.Controls.Primitives /// /// Builds the visual tree for the row header when a new template is applied. /// - protected override void OnTemplateApplied(TemplateAppliedEventArgs e) + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { - base.OnTemplateApplied(e); - _rootElement = e.NameScope.Find(DATAGRIDROWHEADER_elementRootName); if (_rootElement != null) { diff --git a/src/Avalonia.Controls/AutoCompleteBox.cs b/src/Avalonia.Controls/AutoCompleteBox.cs index 9bc7ba9e2f..3e4f47ec8a 100644 --- a/src/Avalonia.Controls/AutoCompleteBox.cs +++ b/src/Avalonia.Controls/AutoCompleteBox.cs @@ -1212,7 +1212,7 @@ namespace Avalonia.Controls /// control /// when a new template is applied. /// - protected override void OnTemplateApplied(TemplateAppliedEventArgs e) + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { if (DropDownPopup != null) @@ -1240,7 +1240,7 @@ namespace Avalonia.Controls OpeningDropDown(false); } - base.OnTemplateApplied(e); + base.OnApplyTemplate(e); } /// diff --git a/src/Avalonia.Controls/ButtonSpinner.cs b/src/Avalonia.Controls/ButtonSpinner.cs index 2ac9319478..7945d63b06 100644 --- a/src/Avalonia.Controls/ButtonSpinner.cs +++ b/src/Avalonia.Controls/ButtonSpinner.cs @@ -121,7 +121,7 @@ namespace Avalonia.Controls } /// - protected override void OnTemplateApplied(TemplateAppliedEventArgs e) + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { IncreaseButton = e.NameScope.Find - protected override void OnTemplateApplied(TemplateAppliedEventArgs e) + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { - base.OnTemplateApplied(e); - Root = e.NameScope.Find(PART_ElementRoot); SelectedMonth = DisplayDate; diff --git a/src/Avalonia.Controls/Calendar/CalendarButton.cs b/src/Avalonia.Controls/Calendar/CalendarButton.cs index b0466967c8..80370df145 100644 --- a/src/Avalonia.Controls/Calendar/CalendarButton.cs +++ b/src/Avalonia.Controls/Calendar/CalendarButton.cs @@ -98,9 +98,8 @@ namespace Avalonia.Controls.Primitives /// /// when a new template is applied. /// - protected override void OnTemplateApplied(TemplateAppliedEventArgs e) + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { - base.OnTemplateApplied(e); SetPseudoClasses(); } diff --git a/src/Avalonia.Controls/Calendar/CalendarDayButton.cs b/src/Avalonia.Controls/Calendar/CalendarDayButton.cs index 3d274d288d..3a39bd10fa 100644 --- a/src/Avalonia.Controls/Calendar/CalendarDayButton.cs +++ b/src/Avalonia.Controls/Calendar/CalendarDayButton.cs @@ -150,11 +150,11 @@ namespace Avalonia.Controls.Primitives } } - protected override void OnTemplateApplied(TemplateAppliedEventArgs e) + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { - base.OnTemplateApplied(e); SetPseudoClasses(); } + private void SetPseudoClasses() { if (_ignoringMouseOverState) diff --git a/src/Avalonia.Controls/Calendar/CalendarItem.cs b/src/Avalonia.Controls/Calendar/CalendarItem.cs index 5a2d1bbfd5..ece0ef97d9 100644 --- a/src/Avalonia.Controls/Calendar/CalendarItem.cs +++ b/src/Avalonia.Controls/Calendar/CalendarItem.cs @@ -268,10 +268,8 @@ namespace Avalonia.Controls.Primitives /// /// when a new template is applied. /// - protected override void OnTemplateApplied(TemplateAppliedEventArgs e) + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { - base.OnTemplateApplied(e); - HeaderButton = e.NameScope.Find