Как предварительно выбрать несколько элементов списка/сетки в приложении C#/XAML для Windows 8?

в моем приложении есть gridview моего пользовательского класса. Я использую пользовательский шаблон данных, и значения связаны с SQLite. Теперь, когда пользователь запускает приложение, определенные элементы (НЕ ОДИНОЧНЫЕ) должны быть предварительно выбраны в представлении сетки/списка. Gridview/listview позволяет множественный выбор. Как я могу добиться этого с помощью свойства SelectedItem?

ОБНОВЛЕНИЕ: я следил за этим, у меня это не работает. Возвращает 0 выборов.

ОБНОВЛЕНИЕ 2: я опубликовал код

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    using (var db = new SQLite.SQLiteConnection(dbpath))
    {
        lvTags.ItemsSource = db.Table<Database.Tag>();  //lvTags is listview

        if (MyList.Count > 0) //MyList is the static list of class "Database.Tag"
        {
            foreach (var item in MyList)
                foreach (var lvitem in lvTags.Items)
                    if (lvitem.Equals(item))
                        lvTags.SelectedItems.Add(lvitem);
        }
    }
}

ОБНОВЛЕНИЕ 3:

public override bool Equals(object obj)
{
    Tag tag = obj as Tag;
    if (this.TagID == tag.TagID && this.TagName == tag.TagName)
        return true;
    else
        return false;
}

person Farhan Ghumra    schedule 04.10.2012    source источник


Ответы (4)


Наконец-то получил ответ от MSDN. Спасибо ForInfo.

XAML-страница

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <ListView x:Name="listView" SelectionMode="Multiple">
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBox Text="{Binding ID}" Margin="0,0,5,0"/>
                    <TextBox Text="{Binding Title}"/>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

C#

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
        LoadData();
    }
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
    }
    ObservableCollection<KiwiItem> sourceColl;
    IList<KiwiItem> selectionList;
    public void LoadData()
    {
        var dbPath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "db.sqlite");

        // Exec (1)
        using (var db = new SQLite.SQLiteConnection(dbPath))
        {
            db.DropTable<KiwiItem>();
            db.CreateTable<KiwiItem>();
            db.RunInTransaction(() =>
            {
                db.Insert(new KiwiItem() { ID = 1, Title = "MyTitle1" });
                db.Insert(new KiwiItem() { ID = 2, Title = "MyTitle2" });
                db.Insert(new KiwiItem() { ID = 3, Title = "MyTitle3" });
                db.Insert(new KiwiItem() { ID = 4, Title = "MyTitle4" });
            });
            this.sourceColl = new ObservableCollection<KiwiItem>();
            this.selectionList = new List<KiwiItem>();
            // Query the db. In practice, fill the sourceColl according to your business scenario
            foreach (KiwiItem item in db.Table<KiwiItem>())
            {
                this.sourceColl.Add(item);
                if (item.ID == 2 || item.ID == 4)
                    this.selectionList.Add(item);
            }
        }

        // Exec (2)
        this.listView.ItemsSource = this.sourceColl;
        foreach (KiwiItem item in this.selectionList)
            this.listView.SelectedItems.Add(item);
    }
}
public class KiwiItem
{
    [SQLite.AutoIncrement, SQLite.PrimaryKey]
    public int ID { get; set; }
    public string Title { get; set; }
}
person Farhan Ghumra    schedule 16.10.2012
comment
Я сделал то же самое, но не работает в моем случае, я не знаю, почему? На самом деле я выбираю некоторые элементы из GridView, а затем возвращаюсь на предыдущую страницу, а затем возвращаюсь на предыдущую страницу, поэтому ранее выбранные элементы должны быть выбраны, чего не происходит. Поможешь мне? - person Rahul Saksule; 08.07.2013

Вы можете использовать свойство SelectedItems.

    //
    // Summary:
    //     Gets the currently selected items.
    //
    // Returns:
    //     A collection of the currently selected items.
    public IList<object> SelectedItems { get; }
person Whyllee    schedule 04.10.2012
comment
+1 за это, хотя эта коллекция предназначена только для чтения, она не может быть привязана к данным, и вам нужно заполнить ее вручную предварительно выбранными элементами. - person Martin Suchan; 04.10.2012
comment
Но как я могу связать данные с предварительно выбранными вручную элементами? У меня есть только SelectedValuePath из базы данных SQLite. - person Farhan Ghumra; 04.10.2012

Вы можете использовать свойство SelectedItems и вызвать SelectedItems.Add() или SelectedItems.Remove(), чтобы добавить/удалить элементы из выбора.

Если вы используете привязку ItemsSource к GridView, вы можете использовать ListViewExtensions.BindableSelection. присоединенное свойство из WinRT XAML Toolkit (оно должно работать и с GridView, так как это подкласс ListViewBase), как в пример страницы.

person Filip Skakun    schedule 04.10.2012
comment
protected override void OnNavigatedTo(NavigationEventArgs e) { foreach (var item in MyList) //MyList is the list of my custom class having integer and string property. { //It contains the object which will be preselected in listview. MyListView.SelectedItems.Add(item); } } Пробовал, не работает. - person Farhan Ghumra; 05.10.2012
comment
Я также попробовал это - person Farhan Ghumra; 05.10.2012
comment
Попробуйте поделиться своим кодом, включая XAML, контекст данных, привязку ItemsSource и т. д., в исходном вопросе. - person Filip Skakun; 05.10.2012
comment
Возможно, Database.Tag из одного из ваших списков никогда не совпадает ни с одним Database.Tag из другого списка. Возможно, вам следует использовать другой тип для ваших моделей представления элементов, чем тот, который вы получаете из базы данных. - person Filip Skakun; 08.10.2012
comment
объекты похожи, с обеих сторон значения одинаковы на if ((Database.Tag)lvitem == item) - person Farhan Ghumra; 09.10.2012
comment
Аналогично != то же самое. Вы внедрили операторы Equals для этого типа? - person Filip Skakun; 09.10.2012
comment
Он возвращает ложь. Пожалуйста, предложите мне какое-нибудь решение. - person Farhan Ghumra; 09.10.2012
comment
переопределить Equals для сравнения свойств, указывающих на то, что элементы одинаковы — либо некоторые идентификаторы, либо все свойства. - person Filip Skakun; 09.10.2012
comment
Я переопределил Equals() (см. Обновление 3). lvTags.SelectedItems имеет объекты, но в представлении списка они не выбраны. - person Farhan Ghumra; 09.10.2012
comment
Вызывается SelectedItems.Add()? - person Filip Skakun; 09.10.2012
comment
да, lvTags.SelectedItems.Add(lvitem) вызывается, а lvTags.SelectedItems.Count также больше нуля, т. е. это то же значение счетчика, что и MyList.Count. Я предлагаю вам дать мне любой образец проекта этого. Я буду вам очень благодарен. - person Farhan Ghumra; 09.10.2012
comment
Извините, я немного потерялся в этом. Я думаю, вам нужно будет переработать свой код, чтобы получить элементы как элементы модели представления и работать со списком, адаптированным для вашего представления, вместо того, чтобы полагаться непосредственно на объекты, поступающие из db.Table‹Database.Tag›(). Возможно, элементы, которые вы пытаетесь добавить в SelectedItems, не совпадают с элементами, назначенными ItemsSource. - person Filip Skakun; 09.10.2012
comment
Вот почему я говорю вам, пожалуйста, дайте мне образец проекта, объясняющий сценарий, который я хочу. Пожалуйста, мне нужна эта функция для моего проекта. - person Farhan Ghumra; 10.10.2012

Я удалил свой первоначальный ответ, так как вы не используете привязку данных, и мой ответ вам не пригодится.

Я только что нашел это, что может быть полезно для вас:

"Свойство SelectedItems доступно только для чтения и не может быть установлено напрямую"

Следовательно, для решения, которое может оказать помощь, см. эта статья.

person Mamta D    schedule 04.10.2012
comment
Я не использую отдельный ListBoxItem (или GridViewItem). Я привязываю источник элементов непосредственно из метода SQLite Query<T>(). - person Farhan Ghumra; 04.10.2012
comment
Обновлен мой ответ на основе вашего комментария. - person Mamta D; 04.10.2012
comment
Спасибо, но я не использую MVVM, мое приложение простое. Не могли бы вы дать мне простое демонстрационное приложение, которое содержит несколько элементов в представлении сетки, и при запуске приложения некоторые из них будут выбраны. - person Farhan Ghumra; 04.10.2012