简体   繁体   中英

Windows 10 uwp listview selection changed not working

Windows 10 uwp app with a listview to just list out strings. First of all, I have an observable collection of strings in my xaml code behind. Because I still dont understand proper data binding in xaml, I am currently adding the strings to tje listview by doing a foreach loop on the observable collection and then doing

Listview1.Items.Add (new TextBlock {Text = myString});

However, is binding in this case as easy as setting my listview ItemsSource to my observablecollection?

My main issue though is I want to know when a user selects a string in the listview and what string they selected. So, I wired up to the listview SelectionChanged event. This event will raise when I select an item in the list, however

 var selectedString = e.AddedItems.First().ToString();

Does not give me the selected string value. Also, there seems to be a possible recursion issue with this event. At one point, my breakpoint hit twice even though I had only selected an item in the listview one time.

So, main question is how to i get the selected string from the listview but also would appreciate suggestions or comments on data binding and if there could be recursion with this event.

EDIT: After trying the last two answers, I am still having some issues here. I cannot get the string that is selected. Using both answers below, I get the same results. First, there is some recursion because clearly the event does fire twice most times even when the list is selected only one time. Also, in both cases, the string is never populated with the selection. In fact, the breakpoint will hit at the line but then skip to the end of the event handler method and I cannot inspect any of the variables or arguments. I even wrapped it up in a try catch block but it never runs the rest of the code in the try block and never catches an exception. All it does is skip to the end of the event handler method but then take me to a file called SharedStubs.g.cs and in there, it hits at the end of this method

        // Signature, Windows.UI.Xaml.UnhandledExceptionEventHandler.Invoke, [rev] [return] [Mcg.CodeGen.ComHRESULTReturnMarshaller] void__int, [rev] [in] [Mcg.CodeGen.WinRTInspectableMarshaller] object____mcg_IInspectable, [rev] [in] [GenericTypeMarshaller]  -> T, 
    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
    [global::System.Runtime.InteropServices.McgGeneratedMarshallingCode]
    internal static int Proc_object__TArg0__<TArg0>(
                object __this, 
                global::System.Runtime.InteropServices.__vtable_IInspectable* unsafe_sender, 
                void* unsafe_e, 
                global::System.IntPtr __methodPtr)
    {
        // Setup
        object sender = default(object);
        TArg0 TArg0__arg = default(TArg0);
        try
        {
            // Marshalling
            sender = global::System.Runtime.InteropServices.McgMarshal.IInspectableToObject(((global::System.IntPtr)unsafe_sender));
            TArg0__arg = (TArg0)global::System.Runtime.InteropServices.McgModuleManager.ComInterfaceToObject(
                                ((global::System.IntPtr)unsafe_e), 
                                typeof(TArg0).TypeHandle
                            );
            // Call to managed method
            global::McgInterop.Intrinsics.HasThisCall__Proc_object__TArg0__<TArg0>(
                                __this, 
                                __methodPtr, 
                                sender, 
                                TArg0__arg
                            );
            global::System.Runtime.InteropServices.DebugAnnotations.PreviousCallContainsUserCode();
            // Return
            return global::McgInterop.Helpers.S_OK;
        }
        catch (global::System.Exception hrExcep)
        {
            // ExceptionReturn
            return global::System.Runtime.InteropServices.McgMarshal.GetHRForExceptionWinRT(hrExcep);
        }
    }

And the sender in this method is ListView. After it hits in this method, the debugger just sort of hangs. I never get a real exception or error and it never really stops. I can hit continue but it just sits idle. So, the above is the only clue I really have. Not sure why this would hit but not the try/catch block and why I would never get any further exception, stack trace, etc...

Thanks!

Can you please try this one?

    private void Listview1_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        TextBlock textBlock = (sender as ListView).SelectedItem as TextBlock;
        string value = textBlock.Text;

        // OR
        string value2 = (e.AddedItems[0] as TextBlock).Text;

        // OR
        string value3 = (e.AddedItems.First() as TextBlock).Text;
    }

First of all, binding string items to a listview requires one line of code. You don't have to create a XAML template for that since you're not binding a object with properties. You can just do this:

Listview1.ItemsSource = YourObservableCollection();

It will bind your collection to your ListView .

As for the selection event, instead of SelectionChanged , you can use ItemClick event. The event args will give you the selected item aka the string by calling e.ClickedItem .

First, enable your ListView1 's IsItemClickEnabled . Set it from false to true . Then add the ItemClick event.

private void ListView1_ItemClick(object sender, ItemClickEventArgs e)
    {
        e.ClickedItem;
    }

This will return the value selected, in your case, the string .

Hope it helps!

you can also use SelectionChanged event to get the value selected by user. Here is how the code will look like :

In XAML :

ListView Name="sourceList"
         ItemsSource="{Binding itemsource}"
         SelectionChanged="sourceList_SelectionChanged"

In Code behind :

private void sourceList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
   string selectedSource = Convert.ToString(((ListView)sender).SelectedItem);
}

You get the currently selected item in a ListView using the SelectedItem property and since you are adding TextBlock elements to the Items collection you should cast the SelectedItem property to a TextBlock and then access its Text property to get the string value:

private void Listview1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    TextBlock textBlock = Listview1.SelectedItem as TextBlock;
    if (textBlock != null)
    {
        string s = textBlock.Text;
    }
}

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