Установить выбранное значение поля со списком - PullRequest
2 голосов
/ 26 ноября 2010

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

ComboBox cbPayee;
// populate with a bunch of "Payee" objects
Payee myObj; // this is my payee object which I get from my database

cbPayee.SelectedValue = myObj // this is what I'd like to do, but it doesn't work

Я думаю, что, возможно, это как-то связано с тем фактом, что объект Payee в поле со списком находится в другом месте памяти, чем myObj, но я не уверен, как это преодолеть.

EDIT

Так заполняется ComboBox

foreach(Payee payee in PayeeManager.GetPayees())
{
    cbPayee.Items.Add(payee);
}

РЕДАКТИРОВАТЬ # 2

Я довольно новичок в WPF, поэтому, возможно, моя привязка настроена неправильно?

<Window x:Class="Budget.TransactionWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="New Transaction" Height="450" Width="450" Loaded="Window_Loaded">
    <Window.Resources>
        <DataTemplate x:Key="PayeeOutput" DataType="Budget.LINQ.Payee">
            <StackPanel Margin="0 0 0 0" Orientation="Horizontal">
                <TextBlock FontWeight="bold" Text="{Binding Path=Name}" />
            </StackPanel>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <ComboBox Height="25" HorizontalAlignment="Left" Margin="73,50,0,0" Name="cbPayee" VerticalAlignment="Top" Width="300" ItemTemplate="{StaticResource PayeeOutput}" />
    </Grid>
</Window>

Ответы [ 5 ]

2 голосов
/ 26 ноября 2010

Чтобы достичь того, что вы хотите, вы можете сделать

cbPayee.SelectedItem = myObj;

Когда вы делаете

cbPayee.SelectedValue = myObj;

происходит то, что .NET ищет объект Payee со свойством, указанным ComboBox.SelectedValuePath равным myObj (которое, скорее всего, вообще не будет объектом), не находит такого объекта и, как результат очищает выбор.

Обновление:

Установка SelectedItem должна просто "просто работать": если объект находится в коллекции Items, он выбирается. Одно предостережение: при поиске объекта WPF по умолчанию будет использовать равенство ссылок . Если вы хотите предоставить свой собственный тест на равенство для этого сценария, вам нужно иметь Payee внедрить IEquatable<Payee>. Если это не работает для вас, дважды проверьте, что вы действительно ссылаетесь на тот же экземпляр (или внедрите IEquatable).

Кроме того, если вы делаете:

cbPayee.SelectedValuePath = "Name";
cbPayee.SelectedValue = "Jack Smith";

тогда поле со списком должно выбрать Payee экземпляр с Name, равным указанному вами. На практике это похоже на реализацию IEquatable<Payee>, когда реализация сравнивает значение Name.

Что именно у вас не работает?

0 голосов
/ 26 ноября 2010

Я только что проверил это, и это работает для меня.Это общий концептуальный код, но я надеюсь, что он поможет.

MyView.xaml

<StackPanel>
    <ComboBox Name="cbPayee" ItemsSource="{Binding Payees}" DisplayMemberPath="Name" SelectedValuePath="ID"  />
    <Button Click="Button_Click" Content="Click me" />
</StackPanel>

MyView.cs

public MyView()
{
    InitializeComponent();
    LoadItems();
    DataContext = this;
}

public IEnumerable<Payee> Payees { get; set; }

private void LoadItems()
{
    Payees = PayeeManager.GetPayees();
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    cbPayee.SelectedValue = new Payee(2, "Steve").ID;
}

Payee.cs

public class Payee
{
    public int ID { get; set; }
    public string Name { get; set; }

    public Payee() { }
    public Payee(int id, string name)
    {
        ID = id;
        Name = name;
    }
}

Технически, я бы рекомендовал вам использовать подход MVVM, где модель представления служит контекстом данных для представления, но это должно привести вас в правильном направлении.

0 голосов
/ 26 ноября 2010

вы можете использовать два разных подхода:

первый:

вы можете определить ValueMember поля со списком для свойства, которое оно должно искать, когда ему данозначение (обычно это идентификатор объекта):

comboBox.ValueMember = "PayeeID";

теперь, когда вы присваиваете comboBox значение типа 4, он будет искать в списке объект, который имеет значение 4;

второй подход:


вы переопределяете метод Equal () Получателя, чтобы сказать, что два объекта одинаковы:

public override Equal(object obj)
{
if (obj is Payee)
   return ((obj as Payee).PayeeID == this.PayeeID;
else
   return false;
}

сейчасВы можете сделать следующее, чтобы выбрать объект из списка:

comboBox.SelectedItem = wantedPayee;

comboBox использует метод Equal, чтобы получить требуемый объект, который будет выбран из его внутреннего списка;

запомнить: когдаВы не отменяете равенство, реализация по умолчанию (AFAIK) будет сравнивать ссылки, чтобы определить равенство.

Наконец, я должен сказать, что этот подход работает для меня, когда я устанавливаю DataSource ComboBox вручную, иЯ не уверен, работает ли он у васнаш путь (Items.Add ())

comboBox.DataSouce = new List () {new Payee {/ некоторые свойства /}};

0 голосов
/ 26 ноября 2010

Вы используете SelectedValue вместо SelectedItem, поэтому ваш оператор = совпадает со свойством объекта, которое соответствует ValueMember вашего ComboBox вместо адреса объекта.

Если вы используете внутренний / статический список объектов, вы заметите, что SelectedValue ВСЕГДА НЕДЕЙСТВИТЕЛЕН.Если вы привязываете источник данных ComboBox, то вы можете установить SelectedValue = myObj.MyProperty, где MyProperty совпадает с ValueMember ComboBox.

Пример:

cbPayee.DisplayMember = "Name";
cbPayee.ValueMember = "ID";
cbPayee.DataSource = myPayeeCollection; // or SqlDataReader, or whatever

...

cbPayee.SelectedValue = myObj.ID;

Если вы 'Если вы используете внутренний / статический список элементов (например, через cbPayee.Items.Add( ... )), вам придется использовать что-то вроде (без установки свойств ComboBox DisplayMember / ValueMember:

cbPayee.Text = myObj.ToString();
0 голосов
/ 26 ноября 2010

в этом случае, я думаю, вам нужно переопределить .ToString () на "selectedvalue" внутри объекта Payee

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...