<Window x:Class="WpfApp28.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp28"
mc:Ignorable="d" WindowState="Maximized"
Title="MainWindow" Height="450" Width="800">
<Grid>
<StackPanel>
<TextBlock Text="Select Book" FontSize="20" FontStyle="Italic" FontWeight="UltraBold" />
<ComboBox x:Name="cbx" ItemsSource="{Binding BooksCollection}"
DisplayMemberPath="{Binding Name}" SelectedIndex="0" FontSize="20"
SelectedValuePath="{Binding Id}" HorizontalAlignment="Left"
VerticalAlignment="Center" VerticalContentAlignment="Center" Height="50"
Width="1200" BorderThickness="3" BorderBrush="Red" >
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}-----{1}-----{2}">
<Binding Path="Id" />
<Binding Path="Name"/>
<Binding Path="Author"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp28
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window,INotifyPropertyChanged
{
private List<Book> booksCollection;
public List<Book> BooksCollection
{
get
{
return booksCollection;
}
set
{
if(value!=booksCollection)
{
booksCollection = value;
OnPropertyChanged("BooksCollection");
}
}
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
Init();
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propName)
{
var handler= PropertyChanged;
if(handler != null)
{
handler.Invoke(this, new PropertyChangedEventArgs(propName));
}
}
void Init()
{
BooksCollection = new List<Book>();
for(int i=0;i<10;i++)
{
BooksCollection.Add(new Book()
{
Id=i+1,
Name=$"Name{Guid.NewGuid().ToString()}",
Author=$"Author{Guid.NewGuid().ToString()}"
});
}
}
}
public class Book
{
public int Id { get; set; }
public string Name { get; set; }
public string Author { get; set; }
public string Description { get; set; }
}
}
![]()
<ComboBox x:Name="cbx" ItemsSource="{Binding BooksCollection}"
DisplayMemberPath="{Binding Name}" SelectedIndex="0" FontSize="20"
SelectedValuePath="{Binding Id}" HorizontalAlignment="Left"
VerticalAlignment="Center" VerticalContentAlignment="Center" Height="50"
Width="1200" BorderThickness="3" BorderBrush="Red" >
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}-----{1}-----{2}">
<Binding Path="Id" />
<Binding Path="Name"/>
<Binding Path="Author"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}-----{1}-----{2}">
<Binding Path="Id" />
<Binding Path="Name"/>
<Binding Path="Author"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
//WpfXamlLoader Load
private static object Load(System.Xaml.XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, bool skipJournaledProperties, object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
{
XamlObjectWriter xamlObjectWriter = null;
XamlContextStack<WpfXamlFrame> stack = new XamlContextStack<WpfXamlFrame>(() => new WpfXamlFrame());
int persistId = 1;
settings.AfterBeginInitHandler = delegate (object sender, XamlObjectEventArgs args)
{
if (EventTrace.IsEnabled(EventTrace.Keyword.KeywordPerf | EventTrace.Keyword.KeywordXamlBaml, EventTrace.Level.Verbose))
{
IXamlLineInfo xamlLineInfo2 = xamlReader as IXamlLineInfo;
int num = -1;
int num2 = -1;
if (xamlLineInfo2 != null && xamlLineInfo2.HasLineInfo)
{
num = xamlLineInfo2.LineNumber;
num2 = xamlLineInfo2.LinePosition;
}
EventTrace.EventProvider.TraceEvent(EventTrace.Event.WClientParseXamlBamlInfo, EventTrace.Keyword.KeywordPerf | EventTrace.Keyword.KeywordXamlBaml, EventTrace.Level.Verbose, (args.Instance == null) ? 0 : PerfService.GetPerfElementID(args.Instance), num, num2);
}
if (args.Instance is UIElement uIElement)
{
uIElement.SetPersistId(persistId++);
}
XamlSourceInfoHelper.SetXamlSourceInfo(args.Instance, args, baseUri);
if (args.Instance is DependencyObject dependencyObject && stack.CurrentFrame.XmlnsDictionary != null)
{
XmlnsDictionary xmlnsDictionary = stack.CurrentFrame.XmlnsDictionary;
xmlnsDictionary.Seal();
XmlAttributeProperties.SetXmlnsDictionary(dependencyObject, xmlnsDictionary);
}
stack.CurrentFrame.Instance = args.Instance;
if (xamlReader is RestrictiveXamlXmlReader && args != null)
{
if (args.Instance is ResourceDictionary resourceDictionary)
{
resourceDictionary.IsUnsafe = true;
}
else if (args.Instance is Frame frame)
{
frame.NavigationService.IsUnsafe = true;
}
else if (args.Instance is NavigationWindow navigationWindow)
{
navigationWindow.NavigationService.IsUnsafe = true;
}
}
};
xamlObjectWriter = ((writerFactory == null) ? new XamlObjectWriter(xamlReader.SchemaContext, settings) : writerFactory.GetXamlObjectWriter(settings));
IXamlLineInfo xamlLineInfo = null;
try
{
xamlLineInfo = xamlReader as IXamlLineInfo;
IXamlLineInfoConsumer xamlLineInfoConsumer = xamlObjectWriter;
bool shouldPassLineNumberInfo = false;
if (xamlLineInfo != null && xamlLineInfo.HasLineInfo && xamlLineInfoConsumer != null && xamlLineInfoConsumer.ShouldProvideLineInfo)
{
shouldPassLineNumberInfo = true;
}
IStyleConnector styleConnector = rootObject as IStyleConnector;
TransformNodes(xamlReader, xamlObjectWriter, onlyLoadOneNode: false, skipJournaledProperties, shouldPassLineNumberInfo, xamlLineInfo, xamlLineInfoConsumer, stack, styleConnector);
xamlObjectWriter.Close();
return xamlObjectWriter.Result;
}
catch (Exception ex)
{
if (CriticalExceptions.IsCriticalException(ex) || !XamlReader.ShouldReWrapException(ex, baseUri))
{
throw;
}
XamlReader.RewrapException(ex, xamlLineInfo, baseUri);
return null;
}
}
internal static void TransformNodes(System.Xaml.XamlReader xamlReader, XamlObjectWriter xamlWriter, bool onlyLoadOneNode, bool skipJournaledProperties, bool shouldPassLineNumberInfo, IXamlLineInfo xamlLineInfo, IXamlLineInfoConsumer xamlLineInfoConsumer, XamlContextStack<WpfXamlFrame> stack, IStyleConnector styleConnector)
{
while (xamlReader.Read())
{
if (shouldPassLineNumberInfo && xamlLineInfo.LineNumber != 0)
{
xamlLineInfoConsumer.SetLineInfo(xamlLineInfo.LineNumber, xamlLineInfo.LinePosition);
}
switch (xamlReader.NodeType)
{
case System.Xaml.XamlNodeType.NamespaceDeclaration:
xamlWriter.WriteNode(xamlReader);
if (stack.Depth == 0 || stack.CurrentFrame.Type != null)
{
stack.PushScope();
for (WpfXamlFrame wpfXamlFrame = stack.CurrentFrame; wpfXamlFrame != null; wpfXamlFrame = (WpfXamlFrame)wpfXamlFrame.Previous)
{
if (wpfXamlFrame.XmlnsDictionary != null)
{
stack.CurrentFrame.XmlnsDictionary = new XmlnsDictionary(wpfXamlFrame.XmlnsDictionary);
break;
}
}
if (stack.CurrentFrame.XmlnsDictionary == null)
{
stack.CurrentFrame.XmlnsDictionary = new XmlnsDictionary();
}
}
stack.CurrentFrame.XmlnsDictionary.Add(xamlReader.Namespace.Prefix, xamlReader.Namespace.Namespace);
break;
case System.Xaml.XamlNodeType.StartObject:
WriteStartObject(xamlReader, xamlWriter, stack);
break;
case System.Xaml.XamlNodeType.GetObject:
xamlWriter.WriteNode(xamlReader);
if (stack.CurrentFrame.Type != null)
{
stack.PushScope();
}
stack.CurrentFrame.Type = stack.PreviousFrame.Property.Type;
break;
case System.Xaml.XamlNodeType.EndObject:
xamlWriter.WriteNode(xamlReader);
if (stack.CurrentFrame.FreezeFreezable && xamlWriter.Result is Freezable freezable && freezable.CanFreeze)
{
freezable.Freeze();
}
if (xamlWriter.Result is DependencyObject dependencyObject && stack.CurrentFrame.XmlSpace.HasValue)
{
XmlAttributeProperties.SetXmlSpace(dependencyObject, stack.CurrentFrame.XmlSpace.Value ? "default" : "preserve");
}
stack.PopScope();
break;
case System.Xaml.XamlNodeType.StartMember:
{
if ((!xamlReader.Member.IsDirective || !(xamlReader.Member == XamlReaderHelper.Freeze)) && xamlReader.Member != XmlSpace.Value && xamlReader.Member != XamlLanguage.Space)
{
xamlWriter.WriteNode(xamlReader);
}
stack.CurrentFrame.Property = xamlReader.Member;
if (!skipJournaledProperties || stack.CurrentFrame.Property.IsDirective)
{
break;
}
WpfXamlMember wpfXamlMember = stack.CurrentFrame.Property as WpfXamlMember;
if (!(wpfXamlMember != null))
{
break;
}
DependencyProperty dependencyProperty = wpfXamlMember.DependencyProperty;
if (dependencyProperty == null || !(dependencyProperty.GetMetadata(stack.CurrentFrame.Type.UnderlyingType) is FrameworkPropertyMetadata frameworkPropertyMetadata) || !frameworkPropertyMetadata.Journal)
{
break;
}
int num = 1;
while (xamlReader.Read())
{
switch (xamlReader.NodeType)
{
case System.Xaml.XamlNodeType.StartMember:
num++;
break;
case System.Xaml.XamlNodeType.StartObject:
{
XamlType type = xamlReader.Type;
XamlType xamlType = type.SchemaContext.GetXamlType(typeof(BindingBase));
XamlType xamlType2 = type.SchemaContext.GetXamlType(typeof(DynamicResourceExtension));
if (num == 1 && (type.CanAssignTo(xamlType) || type.CanAssignTo(xamlType2)))
{
num = 0;
WriteStartObject(xamlReader, xamlWriter, stack);
}
break;
}
case System.Xaml.XamlNodeType.EndMember:
num--;
if (num == 0)
{
xamlWriter.WriteNode(xamlReader);
stack.CurrentFrame.Property = null;
}
break;
case System.Xaml.XamlNodeType.Value:
if (xamlReader.Value is DynamicResourceExtension)
{
WriteValue(xamlReader, xamlWriter, stack, styleConnector);
}
break;
}
if (num == 0)
{
break;
}
}
break;
}
case System.Xaml.XamlNodeType.EndMember:
{
WpfXamlFrame currentFrame = stack.CurrentFrame;
XamlMember property = currentFrame.Property;
if ((!property.IsDirective || !(property == XamlReaderHelper.Freeze)) && property != XmlSpace.Value && property != XamlLanguage.Space)
{
xamlWriter.WriteNode(xamlReader);
}
currentFrame.Property = null;
break;
}
case System.Xaml.XamlNodeType.Value:
WriteValue(xamlReader, xamlWriter, stack, styleConnector);
break;
default:
xamlWriter.WriteNode(xamlReader);
break;
}
if (onlyLoadOneNode)
{
break;
}
}
}
private static readonly Dictionary<ContentType, StreamToObjectFactoryDelegateCore> _objectConvertersCore = new Dictionary<ContentType, StreamToObjectFactoryDelegateCore>(9, new ContentType.WeakComparer());
internal static void RegisterCore(ContentType contentType, StreamToObjectFactoryDelegateCore method)
{
_objectConvertersCore[contentType] = method;
}
/
// Summary:
// Describes the priorities at which operations can be invoked by way of the System.Windows.Threading.Dispatcher.
public enum DispatcherPriority
{
//
// Summary:
// The enumeration value is -1. This is an invalid priority.
Invalid = -1,
//
// Summary:
// The enumeration value is 0. Operations are not processed.
Inactive,
//
// Summary:
// The enumeration value is 1. Operations are processed when the system is idle.
SystemIdle,
//
// Summary:
// The enumeration value is 2. Operations are processed when the application is
// idle.
ApplicationIdle,
//
// Summary:
// The enumeration value is 3. Operations are processed after background operations
// have completed.
ContextIdle,
//
// Summary:
// The enumeration value is 4. Operations are processed after all other non-idle
// operations are completed.
Background,
//
// Summary:
// The enumeration value is 5. Operations are processed at the same priority as
// input.
Input,
//
// Summary:
// The enumeration value is 6. Operations are processed when layout and render has
// finished but just before items at input priority are serviced. Specifically this
// is used when raising the Loaded event.
Loaded,
//
// Summary:
// The enumeration value is 7. Operations processed at the same priority as rendering.
Render,
//
// Summary:
// The enumeration value is 8. Operations are processed at the same priority as
// data binding.
DataBind,
//
// Summary:
// The enumeration value is 9. Operations are processed at normal priority. This
// is the typical application priority.
Normal,
//
// Summary:
// The enumeration value is 10. Operations are processed before other asynchronous
// operations. This is the highest priority.
Send
}
#region Assembly WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// location unknown
// Decompiled with ICSharpCode.Decompiler 8.1.1.7464
#endregion
using System.Security;
using MS.Internal.WindowsBase;
namespace System.Windows.Interop;
//
// Summary:
// Contains message information from a thread's message queue.
[Serializable]
public struct MSG
{
[SecurityCritical]
private IntPtr _hwnd;
[SecurityCritical]
private int _message;
[SecurityCritical]
private IntPtr _wParam;
[SecurityCritical]
private IntPtr _lParam;
[SecurityCritical]
private int _time;
[SecurityCritical]
private int _pt_x;
[SecurityCritical]
private int _pt_y;
//
// Summary:
// Gets or sets the window handle (HWND) to the window whose window procedure receives
// the message.
//
// Returns:
// The window handle (HWND).
public IntPtr hwnd
{
[SecurityCritical]
get
{
return _hwnd;
}
[SecurityCritical]
set
{
SecurityHelper.DemandUnrestrictedUIPermission();
_hwnd = value;
}
}
//
// Summary:
// Gets or sets the message identifier.
//
// Returns:
// The message identifier.
public int message
{
[SecurityCritical]
get
{
return _message;
}
[SecurityCritical]
set
{
SecurityHelper.DemandUnrestrictedUIPermission();
_message = value;
}
}
//
// Summary:
// Gets or sets the wParam value for the message, which specifies additional information
// about the message. The exact meaning depends on the value of the message.
//
// Returns:
// The wParam value for the message.
public IntPtr wParam
{
[SecurityCritical]
get
{
return _wParam;
}
[SecurityCritical]
set
{
SecurityHelper.DemandUnrestrictedUIPermission();
_wParam = value;
}
}
//
// Summary:
// Gets or sets the lParam value that specifies additional information about the
// message. The exact meaning depends on the value of the System.Windows.Interop.MSG.message
// member.
//
// Returns:
// The lParam value for the message.
public IntPtr lParam
{
[SecurityCritical]
get
{
return _lParam;
}
[SecurityCritical]
set
{
SecurityHelper.DemandUnrestrictedUIPermission();
_lParam = value;
}
}
//
// Summary:
// Gets or sets the time at which the message was posted.
//
// Returns:
// The time that the message was posted.
public int time
{
[SecurityCritical]
get
{
return _time;
}
[SecurityCritical]
set
{
SecurityHelper.DemandUnrestrictedUIPermission();
_time = value;
}
}
//
// Summary:
// Gets or sets the x coordinate of the cursor position on the screen, when the
// message was posted.
//
// Returns:
// The x coordinate of the cursor position.
public int pt_x
{
[SecurityCritical]
get
{
return _pt_x;
}
[SecurityCritical]
set
{
SecurityHelper.DemandUnrestrictedUIPermission();
_pt_x = value;
}
}
//
// Summary:
// Gets or sets the y coordinate of the cursor position on the screen, when the
// message was posted.
//
// Returns:
// The y coordinate of the cursor position.
public int pt_y
{
[SecurityCritical]
get
{
return _pt_y;
}
[SecurityCritical]
set
{
SecurityHelper.DemandUnrestrictedUIPermission();
_pt_y = value;
}
}
[SecurityCritical]
[FriendAccessAllowed]
internal MSG(IntPtr hwnd, int message, IntPtr wParam, IntPtr lParam, int time, int pt_x, int pt_y)
{
_hwnd = hwnd;
_message = message;
_wParam = wParam;
_lParam = lParam;
_time = time;
_pt_x = pt_x;
_pt_y = pt_y;
}
}
#if false // Decompilation log
'13' items in cache
------------------
Resolve: 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
Found single assembly: 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
Load from: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\mscorlib.dll'
------------------
Resolve: 'System.Xaml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
Found single assembly: 'System.Xaml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
Load from: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Xaml.dll'
------------------
Resolve: 'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
Found single assembly: 'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
Load from: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.dll'
------------------
Resolve: 'Accessibility, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
Could not find by name: 'Accessibility, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
------------------
Resolve: 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
Found single assembly: 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
Load from: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Core.dll'
------------------
Resolve: 'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
Found single assembly: 'System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
Load from: 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Xml.dll'
------------------
Resolve: 'System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
Could not find by name: 'System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
------------------
Resolve: 'System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
Could not find by name: 'System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
#endif
#region Assembly mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\mscorlib.dll
// Decompiled with ICSharpCode.Decompiler 8.1.1.7464
#endregion
namespace System.Security;
//
// Summary:
// Specifies that code or an assembly performs security-critical operations.
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
[__DynamicallyInvokable]
public sealed class SecurityCriticalAttribute : Attribute
{
private SecurityCriticalScope _val;
//
// Summary:
// Gets the scope for the attribute.
//
// Returns:
// One of the enumeration values that specifies the scope of the attribute. The
// default is System.Security.SecurityCriticalScope.Explicit, which indicates that
// the attribute applies only to the immediate target.
[Obsolete("SecurityCriticalScope is only used for .NET 2.0 transparency compatibility.")]
public SecurityCriticalScope Scope => _val;
//
// Summary:
// Initializes a new instance of the System.Security.SecurityCriticalAttribute class.
[__DynamicallyInvokable]
public SecurityCriticalAttribute()
{
}
//
// Summary:
// Initializes a new instance of the System.Security.SecurityCriticalAttribute class
// with the specified scope.
//
// Parameters:
// scope:
// One of the enumeration values that specifies the scope of the attribute.
public SecurityCriticalAttribute(SecurityCriticalScope scope)
{
_val = scope;
}
}
#if false // Decompilation log
'13' items in cache
#endif