diff --git a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/IProjectFileWriter.cs b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/IProjectFileWriter.cs
index d5542fb6e..26c1a8a58 100644
--- a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/IProjectFileWriter.cs
+++ b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/IProjectFileWriter.cs
@@ -34,9 +34,8 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
 		/// 
 		/// The target to write to.
 		/// The information about the project being created.
-		/// A collection of source files to be included into the project, each item is a pair
-		/// of the project entry type and the file path.
+		/// A collection of source files to be included into the project.
 		/// The module being decompiled.
-		void Write(TextWriter target, IProjectInfoProvider project, IEnumerable<(string itemType, string fileName)> files, PEFile module);
+		void Write(TextWriter target, IProjectInfoProvider project, IEnumerable files, PEFile module);
 	}
 }
diff --git a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterDefault.cs b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterDefault.cs
index af98d6045..eb383ba75 100644
--- a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterDefault.cs
+++ b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterDefault.cs
@@ -25,6 +25,7 @@ using System.Xml;
 
 using ICSharpCode.Decompiler.Metadata;
 using ICSharpCode.Decompiler.Solution;
+using ICSharpCode.Decompiler.Util;
 
 namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
 {
@@ -43,7 +44,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
 		public void Write(
 			TextWriter target,
 			IProjectInfoProvider project,
-			IEnumerable<(string itemType, string fileName)> files,
+			IEnumerable files,
 			PEFile module)
 		{
 			const string ns = "http://schemas.microsoft.com/developer/msbuild/2003";
@@ -162,13 +163,18 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
 				}
 				w.WriteEndElement(); //  (References)
 
-				foreach (IGrouping gr in from f in files group f.fileName by f.itemType into g orderby g.Key select g)
+				foreach (IGrouping gr in files.GroupBy(f => f.ItemType).OrderBy(g => g.Key))
 				{
 					w.WriteStartElement("ItemGroup");
-					foreach (string file in gr.OrderBy(f => f, StringComparer.OrdinalIgnoreCase))
+					foreach (var item in gr.OrderBy(f => f.FileName, StringComparer.OrdinalIgnoreCase))
 					{
 						w.WriteStartElement(gr.Key);
-						w.WriteAttributeString("Include", file);
+						w.WriteAttributeString("Include", item.FileName);
+						if (item.AdditionalProperties != null)
+						{
+							foreach (var (key, value) in item.AdditionalProperties)
+								w.WriteAttributeString(key, value);
+						}
 						w.WriteEndElement();
 					}
 					w.WriteEndElement();
diff --git a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterSdkStyle.cs b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterSdkStyle.cs
index 61bb6d21f..b5273f1d5 100644
--- a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterSdkStyle.cs
+++ b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/ProjectFileWriterSdkStyle.cs
@@ -66,7 +66,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
 		public void Write(
 			TextWriter target,
 			IProjectInfoProvider project,
-			IEnumerable<(string itemType, string fileName)> files,
+			IEnumerable files,
 			PEFile module)
 		{
 			using (XmlTextWriter xmlWriter = new XmlTextWriter(target))
@@ -76,7 +76,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
 			}
 		}
 
-		static void Write(XmlTextWriter xml, IProjectInfoProvider project, IEnumerable<(string itemType, string fileName)> files, PEFile module)
+		static void Write(XmlTextWriter xml, IProjectInfoProvider project, IEnumerable files, PEFile module)
 		{
 			xml.WriteStartElement("Project");
 
@@ -188,27 +188,27 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
 			}
 		}
 
-		static void WriteMiscellaneousPropertyGroup(XmlTextWriter xml, IEnumerable<(string itemType, string fileName)> files)
+		static void WriteMiscellaneousPropertyGroup(XmlTextWriter xml, IEnumerable files)
 		{
-			var (itemType, fileName) = files.FirstOrDefault(t => t.itemType == "ApplicationIcon");
+			var (itemType, fileName) = files.FirstOrDefault(t => t.ItemType == "ApplicationIcon");
 			if (fileName != null)
 				xml.WriteElementString("ApplicationIcon", fileName);
 
-			(itemType, fileName) = files.FirstOrDefault(t => t.itemType == "ApplicationManifest");
+			(itemType, fileName) = files.FirstOrDefault(t => t.ItemType == "ApplicationManifest");
 			if (fileName != null)
 				xml.WriteElementString("ApplicationManifest", fileName);
 
-			if (files.Any(t => t.itemType == "EmbeddedResource"))
+			if (files.Any(t => t.ItemType == "EmbeddedResource"))
 				xml.WriteElementString("RootNamespace", string.Empty);
 			// TODO: We should add CustomToolNamespace for resources, otherwise we should add empty RootNamespace
 		}
 
-		static void WriteResources(XmlTextWriter xml, IEnumerable<(string itemType, string fileName)> files)
+		static void WriteResources(XmlTextWriter xml, IEnumerable files)
 		{
 			// remove phase
-			foreach (var (itemType, fileName) in files.Where(t => t.itemType == "EmbeddedResource"))
+			foreach (var item in files.Where(t => t.ItemType == "EmbeddedResource"))
 			{
-				string buildAction = Path.GetExtension(fileName).ToUpperInvariant() switch {
+				string buildAction = Path.GetExtension(item.FileName).ToUpperInvariant() switch {
 					".CS" => "Compile",
 					".RESX" => "EmbeddedResource",
 					_ => "None"
@@ -217,18 +217,23 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
 					continue;
 
 				xml.WriteStartElement(buildAction);
-				xml.WriteAttributeString("Remove", fileName);
+				xml.WriteAttributeString("Remove", item.FileName);
 				xml.WriteEndElement();
 			}
 
 			// include phase
-			foreach (var (itemType, fileName) in files.Where(t => t.itemType == "EmbeddedResource"))
+			foreach (var item in files.Where(t => t.ItemType == "EmbeddedResource"))
 			{
-				if (Path.GetExtension(fileName) == ".resx")
+				if (Path.GetExtension(item.FileName) == ".resx")
 					continue;
 
 				xml.WriteStartElement("EmbeddedResource");
-				xml.WriteAttributeString("Include", fileName);
+				xml.WriteAttributeString("Include", item.FileName);
+				if (item.AdditionalProperties != null)
+				{
+					foreach (var (key, value) in item.AdditionalProperties)
+						xml.WriteAttributeString(key, value);
+				}
 				xml.WriteEndElement();
 			}
 		}
diff --git a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs
index e342df4a6..852de74a7 100644
--- a/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs
+++ b/ICSharpCode.Decompiler/CSharp/ProjectDecompiler/WholeProjectDecompiler.cs
@@ -151,8 +151,8 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
 			TargetDirectory = targetDirectory;
 			directories.Clear();
 			var resources = WriteResourceFilesInProject(moduleDefinition).ToList();
-			var files = WriteCodeFilesInProject(moduleDefinition, resources.SelectMany(r => r.partialTypes ?? Enumerable.Empty()).ToList(), cancellationToken).ToList();
-			files.AddRange(resources.Select(r => (r.itemType, r.fileName)));
+			var files = WriteCodeFilesInProject(moduleDefinition, resources.SelectMany(r => r.PartialTypes ?? Enumerable.Empty()).ToList(), cancellationToken).ToList();
+			files.AddRange(resources);
 			files.AddRange(WriteMiscellaneousFilesInProject(moduleDefinition));
 			if (StrongNameKeyFile != null)
 			{
@@ -190,7 +190,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
 			return decompiler;
 		}
 
-		IEnumerable<(string itemType, string fileName)> WriteAssemblyInfo(DecompilerTypeSystem ts, CancellationToken cancellationToken)
+		IEnumerable WriteAssemblyInfo(DecompilerTypeSystem ts, CancellationToken cancellationToken)
 		{
 			var decompiler = CreateDecompiler(ts);
 			decompiler.CancellationToken = cancellationToken;
@@ -205,10 +205,10 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
 			{
 				syntaxTree.AcceptVisitor(new CSharpOutputVisitor(w, Settings.CSharpFormattingOptions));
 			}
-			return new[] { ("Compile", assemblyInfo) };
+			return new[] { new ProjectItemInfo("Compile", assemblyInfo) };
 		}
 
-		IEnumerable<(string itemType, string fileName)> WriteCodeFilesInProject(Metadata.PEFile module, IList partialTypes, CancellationToken cancellationToken)
+		IEnumerable WriteCodeFilesInProject(Metadata.PEFile module, IList partialTypes, CancellationToken cancellationToken)
 		{
 			var metadata = module.Metadata;
 			var files = module.Metadata.GetTopLevelTypeDefinitions().Where(td => IncludeTypeWhenDecompilingProject(module, td))
@@ -229,7 +229,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
 				progress.TotalUnits = files.Count;
 			}
 
-			return files.Select(f => ("Compile", f.Key)).Concat(WriteAssemblyInfo(ts, cancellationToken));
+			return files.Select(f => new ProjectItemInfo("Compile", f.Key)).Concat(WriteAssemblyInfo(ts, cancellationToken));
 
 			string GetFileFileNameForHandle(TypeDefinitionHandle h)
 			{
@@ -308,7 +308,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
 		#endregion
 
 		#region WriteResourceFilesInProject
-		protected virtual IEnumerable<(string itemType, string fileName, List partialTypes)> WriteResourceFilesInProject(Metadata.PEFile module)
+		protected virtual IEnumerable WriteResourceFilesInProject(Metadata.PEFile module)
 		{
 			foreach (var r in module.Resources.Where(r => r.ResourceType == ResourceType.Embedded))
 			{
@@ -318,7 +318,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
 				if (r.Name.EndsWith(".resources", StringComparison.OrdinalIgnoreCase))
 				{
 					bool decodedIntoIndividualFiles;
-					var individualResources = new List<(string itemType, string fileName, List partialTypes)>();
+					var individualResources = new List();
 					try
 					{
 						var resourcesFile = new ResourcesFile(stream);
@@ -378,12 +378,12 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
 						stream.Position = 0;
 						stream.CopyTo(fs);
 					}
-					yield return ("EmbeddedResource", fileName, null);
+					yield return new ProjectItemInfo("EmbeddedResource", fileName).With("LogicalName", r.Name);
 				}
 			}
 		}
 
-		protected virtual IEnumerable<(string itemType, string fileName, List partialTypes)> WriteResourceToFile(string fileName, string resourceName, Stream entryStream)
+		protected virtual IEnumerable WriteResourceToFile(string fileName, string resourceName, Stream entryStream)
 		{
 			if (fileName.EndsWith(".resources", StringComparison.OrdinalIgnoreCase))
 			{
@@ -398,7 +398,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
 							writer.AddResource(entry.Key, entry.Value);
 						}
 					}
-					return new[] { ("EmbeddedResource", resx, (List)null) };
+					return new[] { new ProjectItemInfo("EmbeddedResource", resx).With("LogicalName", resourceName) };
 				}
 				catch (BadImageFormatException)
 				{
@@ -413,7 +413,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
 			{
 				entryStream.CopyTo(fs);
 			}
-			return new[] { ("EmbeddedResource", fileName, (List)null) };
+			return new[] { new ProjectItemInfo("EmbeddedResource", fileName).With("LogicalName", resourceName) };
 		}
 
 		string GetFileNameForResource(string fullName)
@@ -444,7 +444,7 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
 		#endregion
 
 		#region WriteMiscellaneousFilesInProject
-		protected virtual IEnumerable<(string itemType, string fileName)> WriteMiscellaneousFilesInProject(PEFile module)
+		protected virtual IEnumerable WriteMiscellaneousFilesInProject(PEFile module)
 		{
 			var resources = module.Reader.ReadWin32Resources();
 			if (resources == null)
@@ -454,21 +454,21 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
 			if (appIcon != null)
 			{
 				File.WriteAllBytes(Path.Combine(TargetDirectory, "app.ico"), appIcon);
-				yield return ("ApplicationIcon", "app.ico");
+				yield return new ProjectItemInfo("ApplicationIcon", "app.ico");
 			}
 
 			byte[] appManifest = CreateApplicationManifest(resources);
 			if (appManifest != null && !IsDefaultApplicationManifest(appManifest))
 			{
 				File.WriteAllBytes(Path.Combine(TargetDirectory, "app.manifest"), appManifest);
-				yield return ("ApplicationManifest", "app.manifest");
+				yield return new ProjectItemInfo("ApplicationManifest", "app.manifest");
 			}
 
 			var appConfig = module.FileName + ".config";
 			if (File.Exists(appConfig))
 			{
 				File.Copy(appConfig, Path.Combine(TargetDirectory, "app.config"), overwrite: true);
-				yield return ("ApplicationConfig", Path.GetFileName(appConfig));
+				yield return new ProjectItemInfo("ApplicationConfig", Path.GetFileName(appConfig));
 			}
 		}
 
@@ -753,4 +753,25 @@ namespace ICSharpCode.Decompiler.CSharp.ProjectDecompiler
 			return TargetServices.DetectTargetFramework(module).Moniker != null;
 		}
 	}
+
+	public record struct ProjectItemInfo(string ItemType, string FileName)
+	{
+		public List PartialTypes { get; set; } = null;
+
+		public Dictionary AdditionalProperties { get; set; } = null;
+
+		public ProjectItemInfo With(string name, string value)
+		{
+			AdditionalProperties ??= new Dictionary();
+			AdditionalProperties.Add(name, value);
+			return this;
+		}
+
+		public ProjectItemInfo With(IEnumerable> pairs)
+		{
+			AdditionalProperties ??= new Dictionary();
+			AdditionalProperties.AddRange(pairs);
+			return this;
+		}
+	}
 }
diff --git a/ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs b/ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs
index be0a6ae1c..4ac408de5 100644
--- a/ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs
+++ b/ILSpy.BamlDecompiler/BamlResourceNodeFactory.cs
@@ -72,6 +72,8 @@ namespace ILSpy.BamlDecompiler
 			{
 				fileName = Path.ChangeExtension(fileName, ".xaml");
 			}
+			context.AdditionalProperties.Add("Generator", "MSBuild:Compile");
+			context.AdditionalProperties.Add("SubType", "Designer");
 			string saveFileName = Path.Combine(context.DecompilationOptions.SaveAsProjectDirectory, fileName);
 			Directory.CreateDirectory(Path.GetDirectoryName(saveFileName));
 			result.Xaml.Save(saveFileName);
diff --git a/ILSpy/Languages/CSharpLanguage.cs b/ILSpy/Languages/CSharpLanguage.cs
index 703fcd3a6..a5cd1e1a0 100644
--- a/ILSpy/Languages/CSharpLanguage.cs
+++ b/ILSpy/Languages/CSharpLanguage.cs
@@ -517,7 +517,7 @@ namespace ICSharpCode.ILSpy
 				this.options = options;
 			}
 
-			protected override IEnumerable<(string itemType, string fileName, List partialTypes)> WriteResourceToFile(string fileName, string resourceName, Stream entryStream)
+			protected override IEnumerable WriteResourceToFile(string fileName, string resourceName, Stream entryStream)
 			{
 				var context = new ResourceFileHandlerContext(options);
 				foreach (var handler in App.ExportProvider.GetExportedValues())
@@ -527,7 +527,7 @@ namespace ICSharpCode.ILSpy
 						entryStream.Position = 0;
 						fileName = handler.WriteResourceToFile(assembly, fileName, entryStream, context);
 
-						return new[] { (handler.EntryType, fileName, context.PartialTypes) };
+						return new[] { new ProjectItemInfo(handler.EntryType, fileName) { PartialTypes = context.PartialTypes }.With(context.AdditionalProperties) };
 					}
 				}
 				return base.WriteResourceToFile(fileName, resourceName, entryStream);
diff --git a/ILSpy/Languages/IResourceFileHandler.cs b/ILSpy/Languages/IResourceFileHandler.cs
index 8fe336f06..19b977ac5 100644
--- a/ILSpy/Languages/IResourceFileHandler.cs
+++ b/ILSpy/Languages/IResourceFileHandler.cs
@@ -36,6 +36,9 @@ namespace ICSharpCode.ILSpy
 		readonly List partialTypes = new();
 		internal List PartialTypes => partialTypes;
 
+		readonly Dictionary additionalProperties = new();
+		public Dictionary AdditionalProperties => additionalProperties;
+
 		public DecompilationOptions DecompilationOptions { get; }
 
 		public ResourceFileHandlerContext(DecompilationOptions options)