简体   繁体   中英

Accessing cell text when using the GridView of a ListView in WPF

I am really struggling with the WPF ListView at the moment, I imagine a missing something really dumb but after a couple of hours of googling I though I had better ask.

I am trying to access the text contents of individual cells in a ListView which has been created with a GridView thus:

<ListView Name="MyListView">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Foo" DisplayMemberBinding="{Binding Foo}"/>
            <GridViewColumn Header="Bar" DisplayMemberBinding="{Binding Bar}"/>
        </GridView>
    </ListView.View>
</ListView>

I am adding to the list view as so:

var foobars = new ObservableCollection<Foobar>();
foobars.Add(new Foobar { Foo = "Hello", Bar = "world" });
MyListView.ItemsSource = foobars;

Now I would like to grab the word "world" from the second column of the first row. If this was WinForms I would type:

var word = (string)(((ListViewItem)MyListView.Items[0]).SubItems[1]);

I can't find any way to do this in WPF: I realize I could do:

var word = ((Foobar)MyListView.Items[0]).Bar;

But in my real application the text which appears in the ListView has been through one of a couple of ValueConverters based on which column it is in, and so is not the same as the text in the binding object. I just need to grab the text which is being displayed to the user, not the underlying data object.

Do any of the code gurus here have any advice??

Cheers,

Gavin

Ok, found a ugly way to do this. Here is the code to get "world" from the first row, second column cell:

var columns = ((GridView) MyListView.View).Columns;
var foobar = (Foobar)MyListView.Items[0];
var result = (string)DataBinder.Eval(foobar, (Binding) columns[0].DisplayMemberBinding);

This is using a helper class (thanks to http://social.expression.microsoft.com/Forums/en-US/wpf/thread/315d2442-b978-4e5f-89cd-1004a51f390d/ you saved alot of my hair from being pulled):

public class DataBinder
{
    private static readonly DependencyProperty BindingEvalProperty = DependencyProperty.RegisterAttached(
        "BindingEval",
        typeof(Object),
        typeof(DependencyObject),
        new UIPropertyMetadata(null));

    public static Object Eval(Object data, Binding binding)
    {
        var newbinding = new Binding {Path = binding.Path, Converter = binding.Converter, Source = data};
        var evalobj = new DependencyObject();
        BindingOperations.SetBinding(evalobj, BindingEvalProperty, newbinding);
        return evalobj.GetValue(BindingEvalProperty);
    }
}

So this is grabbing the binding object from the second column and evaluating it against the data object associated with the first row the same way the underlying GridView code would be. This will work for my application, but if anyone has a neater solution please feel free to post an answer!

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