简体   繁体   中英

ListView ItemsSource dependent on SelectedItem of another ListView

Is after my function "initializeME" is executed everything I did in there lost, because the variables are local to the function?

I got two ListViews, both filled with an ObservableCollection. Every Item of the first ListView represents an Object of Type "Kunde", wich itself contains an ObservableCollection to be shown in the second ListView, if the according ListViewItem is selected.

( I am new to c#/.NET/VS and aware of MVVM etc. - but want to get my head around of the basics first. Please excuse if my question is not well formulated, or if it exists already - I wasn't able to find a solution and need to learn everythin on my own, in VisualStudio happens a lot automatically, compared with c, and I don't know, exactly what happens there. )

Here is the MainWindow XAML:

            <Window x:Class="Licencer.MainWindow"
                    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    Title="MainWindow" Height="400" Width="600" Name="Main">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="20" />
                        <RowDefinition Height="50" />
                        <RowDefinition Height="250*" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="100" />
                        <ColumnDefinition Width="200*" />
                    </Grid.ColumnDefinitions>
                    <DockPanel Grid.Column="0" Grid.ColumnSpan="2">
                        <Menu DockPanel.Dock="Top">
                            <MenuItem Header="_Datei">
                                <MenuItem Header="_Neu" />
                                <MenuItem Header="_Öffnen" />
                                <MenuItem Header="_Speichern" />
                                <Separator />
                                <MenuItem Header="_Schließen" />
                            </MenuItem>
                            <MenuItem Header="_Kunde">
                                <MenuItem Header="_Neu" />
                                <MenuItem Header="_Löschen" />
                                <MenuItem Header="_Bearbeiten" />
                            </MenuItem>
                            <MenuItem Header="Produkt">
                                <MenuItem Header="_Neu" />
                                <MenuItem Header="_Löschen" />
                                <MenuItem Header="_Lizenz...">
                                    <MenuItem Header="_Hinzufügen" />
                                    <MenuItem Header="_Entfernen" />
                                </MenuItem>
                            </MenuItem>
                        </Menu>
                    </DockPanel>
                    <GroupBox Grid.Column="0" Grid.Row="2" Header="Kunden">
                        <ListView x:Name="ListView_Kunden" MouseDoubleClick="getSelectedItem">
                        </ListView>
                    </GroupBox>
                    <GroupBox Grid.Column="1" Grid.Row="2" Header="Produkte">
                        <ListView x:Name="ListView_Produkte">
                            <ListView.View>
                                <GridView>
                                    <GridViewColumn Header="Produktname" Width="auto" DisplayMemberBinding="{Binding Name}" />
                                    <GridViewColumn Header="Hersteller" Width="auto" DisplayMemberBinding="{Binding Hersteller}" />
                                    <GridViewColumn Header="Anzahl" Width="auto" DisplayMemberBinding="{Binding LizenzAnzahl}" />
                                </GridView>
                            </ListView.View>
                        </ListView>
                    </GroupBox>
                </Grid>
            </Window>

And the MainWindow.xaml.cs:

            using System;
            using System.Collections.Generic;
            using System.Linq;
            using System.Text;
            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;
            using Licencer;

            namespace Licencer
            {
                /// <summary>
                /// Interaktionslogik für MainWindow.xaml
                /// </summary>
                public partial class MainWindow : Window
                {
                    public Kunden alleKunden { get; set; }
                    public Produkte alleProdukte { get; set; }
                    public Produkte leerProdukte { get; set; }

                    public void initializeME()
                    {

                        alleKunden = new Kunden();
                        alleProdukte = new Produkte();
                        leerProdukte = new Produkte();

                        Kunde Heinrich = new Kunde("Heinrich", "Musterstrasse 1", "heinrich@mail.de");
                        Kunde Dietrich = new Kunde("Dietrich", "Musterstrasse 2", "dietrich@mail.de");

                        Produkt test0 = new Produkt("Zuerst da", "Die Firma", 400);
                        Produkt test1 = new Produkt("test1", "tester & Co. KG", 25);
                        Produkt test2 = new Produkt("test2", "tester GmbH", 200);
                        Produkt test3 = new Produkt("test3", "Firma AG", 40);

                        Heinrich.OwnedProducts.Add(test1);
                        Dietrich.OwnedProducts.Add(test2);
                        Dietrich.OwnedProducts.Add(test3);

                        alleKunden.Add(Heinrich);
                        alleKunden.Add(Dietrich);

                        alleProdukte.Add(test0);
                        leerProdukte.Add(test0);

                        this.ListView_Kunden.ItemsSource = alleKunden;
                        this.ListView_Produkte.ItemsSource = alleProdukte;
                    }

                    public MainWindow()
                    {
                        initializeME();
                        InitializeComponent();
                    }

                    private void getSelectedItem(object sender, MouseButtonEventArgs e)
                    {

                        System.Windows.MessageBox.Show(ListView_Kunden.SelectedItem.ToString());

                        if ((Kunde)ListView_Kunden.SelectedItem != null)
                        {
                            Kunde current = (Kunde)ListView_Kunden.SelectedItem;
                            this.alleProdukte = current.OwnedProducts;
                        }
                        else
                        {
                            this.alleProdukte = leerProdukte;
                        }
                    }



                }
            }

And here the rest of the project:

            namespace Licencer
            {
                public class Kunde
                {
                    public Produkte OwnedProducts { get; set; }
                    public string Name { get; set; }
                    public string Anschrift { get; set; }
                    public string eMail { get; set; }

                    public override string ToString()
                    {
                        return this.Name;
                    }

                    public Kunde(string name, string anschrift, string mail)
                    {
                        this.Anschrift = anschrift;
                        this.eMail = mail;
                        this.Name = name;
                    }

                }
            }

            using System;
            using System.Collections.Generic;
            using System.Linq;
            using System.Text;

            namespace Licencer
            {
                public class Produkt
                {
                    public UInt64 LizenzAnzahl { get; set; }
                    public string Name { get; set; }
                    public string Hersteller { get; set; }

                    public Produkt(string name, string hersteller, UInt64 anzahl)
                    {
                        this.LizenzAnzahl = anzahl;
                        this.Hersteller = hersteller;
                        this.Name = name;
                    }
                }
            }

            using System;
            using System.Collections.Generic;
            using System.Linq;
            using System.Text;
            using System.Collections.ObjectModel;

            namespace Licencer
            {
                public class Kunden : ObservableCollection<Kunde>
                {

                }
            }

            using System;
            using System.Collections.Generic;
            using System.Linq;
            using System.Text;
            using System.Collections.ObjectModel;

            namespace Licencer
            {
                public class Produkte : ObservableCollection<Produkt>
                {

                }
            }

The Error:

System.Reflection.TargetInvocationException wurde nicht behandelt.
  HResult=-2146232828
  Message=Ein Aufrufziel hat einen Ausnahmefehler verursacht.
  Source=mscorlib
  StackTrace:
       bei System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
       bei System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
       bei System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
       bei System.Activator.CreateInstance(Type type, Boolean nonPublic)
       bei System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, StackCrawlMark& stackMark)
       bei System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
       bei System.Activator.CreateInstance(Type type, Object[] args)
       bei System.Xaml.Schema.SafeReflectionInvoker.CreateInstanceCritical(Type type, Object[] arguments)
       bei System.Xaml.Schema.SafeReflectionInvoker.CreateInstance(Type type, Object[] arguments)
       bei System.Xaml.Schema.XamlTypeInvoker.CreateInstance(Object[] arguments)
       bei MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateInstanceWithCtor(XamlType xamlType, Object[] args)
       bei MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateInstance(XamlType xamlType, Object[] args)
       bei System.Xaml.XamlObjectWriter.Logic_CreateAndAssignToParentStart(ObjectWriterContext ctx)
       bei System.Xaml.XamlObjectWriter.WriteStartMember(XamlMember property)
       bei System.Xaml.XamlWriter.WriteNode(XamlReader reader)
       bei System.Windows.Markup.WpfXamlLoader.TransformNodes(XamlReader xamlReader, XamlObjectWriter xamlWriter, Boolean onlyLoadOneNode, Boolean skipJournaledProperties, Boolean shouldPassLineNumberInfo, IXamlLineInfo xamlLineInfo, IXamlLineInfoConsumer xamlLineInfoConsumer, XamlContextStack`1 stack, IStyleConnector styleConnector)
       bei System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
       bei System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)
       bei System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
       bei System.Windows.Application.LoadBamlStreamWithSyncInfo(Stream stream, ParserContext pc)
       bei System.Windows.Application.LoadComponent(Uri resourceLocator, Boolean bSkipJournaledProperties)
       bei System.Windows.Application.DoStartup()
       bei System.Windows.Application.<.ctor>b__1(Object unused)
       bei System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
       bei MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
       bei System.Windows.Threading.DispatcherOperation.InvokeImpl()
       bei System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
       bei System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       bei System.Windows.Threading.DispatcherOperation.Invoke()
       bei System.Windows.Threading.Dispatcher.ProcessQueue()
       bei System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       bei MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       bei MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
       bei System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
       bei MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
       bei System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
       bei MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       bei MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
       bei System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
       bei System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
       bei System.Windows.Threading.Dispatcher.Run()
       bei System.Windows.Application.RunDispatcher(Object ignore)
       bei System.Windows.Application.RunInternal(Window window)
       bei System.Windows.Application.Run(Window window)
       bei System.Windows.Application.Run()
       bei Licencer.App.Main() in H:\Programmierung\DotNet Tutorial\VisualStudio2010\Projekte\Licencer\Licencer\obj\x86\Debug\App.g.cs:Zeile 0.
       bei System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       bei System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       bei System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       bei System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       bei System.Threading.ThreadHelper.ThreadStart()
  InnerException: System.NullReferenceException
       HResult=-2147467261
       Message=Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
       Source=Licencer
       StackTrace:
            bei Licencer.MainWindow.initializeME() in H:\Programmierung\DotNet Tutorial\VisualStudio2010\Projekte\Licencer\Licencer\MainWindow.xaml.cs:Zeile 42.
            bei Licencer.MainWindow..ctor() in H:\Programmierung\DotNet Tutorial\VisualStudio2010\Projekte\Licencer\Licencer\MainWindow.xaml.cs:Zeile 58.
       InnerException: 

For those that know the basics of WPF, here is one way to fulfil the requirements, where Items is the outer collection and InnerItems is the collection property from the type of class that is inside the Items collection:

<ListBox ItemsSource="{Binding Items}" IsSynchronizedWithCurrentItem="True"/>
<ListBox ItemsSource="{Binding Items/InnerItems}" 
    IsSynchronizedWithCurrentItem="True" /> 

This Items/InnerItems Binding syntax above simply means that WPF should read the source value from the InnerItems property of the current item from the Items collection.

The compiler is pointing you where the error is:

bei Licencer.MainWindow.initializeME() in H:\\Programmierung\\DotNet Tutorial\\VisualStudio2010\\Projekte\\Licencer\\Licencer\\MainWindow.xaml.cs:Zeile 42.

You are accessing the OwnedProducts property but it has never been initialized, so it is null :

Heinrich.OwnedProducts.Add(test1);

To fix it create the object in the constructor:

public Kunde(string name, string anschrift, string mail)
{
    this.Anschrift = anschrift;
    this.eMail = mail;
    this.Name = name;
    this.OwnedProducts = new Produkte();
}

Also, beware of using the components before they have been initialized. Your MainWindow constructor should look this instead:

public MainWindow()
{
    InitializeComponent(); // Call this first
    initializeME();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM