Wpf ComboBoxItem show multi fields
<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