WPF ComboBox не обновляет источник
Я пытаюсь заставить WPF combobox работать (внутри Wpftoolkit Datagrid), и у меня возникли проблемы с правильным выравниванием всех частей. Я использую Linq для сущностей, и я устанавливаю общий datacontext для результатов запроса Linq:
private void LoadDonationGrid()
{
donationGrid.ItemsSource = from donations in entities.Donation
.Include("Family")
.Include("PledgeYear")
.Include("DonationPurpose")
from donationPurposes in entities.DonationPurpose
select new { donations, donationPurposes };
}
у меня также есть свойство страницы в моем коде, за которым предоставляется ItemsSource для combobox:
private IEnumerable donationPurposeList;
public IEnumerable DonationPurposeList
{
get
{
if (donationPurposeList == null)
{
donationPurposeList = from dp in entities.DonationPurpose
select dp;
}
return donationPurposeList.ToList();
}
}
XAML для combobox выглядит следующим образом:
<tk:DataGridTemplateColumn Header="Purpose">
<tk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=donations.DonationPurpose.Description, Mode=TwoWay}" />
</DataTemplate>
</tk:DataGridTemplateColumn.CellTemplate>
<tk:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox Name="cboDonationPurpose"
SelectedValue="{Binding Path=donations.DonationPurposeID, Mode=TwoWay}"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type Page},Mode=FindAncestor},Path=DonationPurposeList}"
DisplayMemberPath="Description"
SelectedValuePath="DonationPurposeID"
/>
</DataTemplate>
</tk:DataGridTemplateColumn.CellEditingTemplate>
</tk:DataGridTemplateColumn>
и все вроде работайте правильно, т. е. соответствующие значения отображаются в поле со списком, вплоть до того момента, когда фокус покидает поле со списком. В этот момент отображаемое значение возвращается к исходному значению, а не к вновь выбранному значению. Я попытался использовать SelectedItem вместо SelectedValue, но это заканчивается тем, что выбранное значение не отображается в ComboBox. Я немного озадачен: кажется, этот бит должен работать.
отредактировано 3/2/09: я все еще озадачен этим. Отмечу что в моем datagrid любые простые столбцы данных (например, "DataGridTextColumn") обновляют базовый источник данных так, как вы ожидаете. Но любое обновление любого из моих шаблонных столбцов ("DataGridTemplateColumn") или столбцов ComboBox ("DataGridComboBoxColumn") не работает: базовый источник данных никогда не обновляется. Конечно, другие люди пытались использовать WPF.Toolkit datagrid и получил этот сценарий для работы , но я посмотрел на весь образец кода, и я делаю в основном то, что он говорит сделайте (в пределах ограничений моего решения), поэтому я чешу голову, почему это не работает.
какие мысли?
3 ответов
у меня была аналогичная проблема (на которую я потратил дни разочарования), и я обнаружил, что изменение UpdateSourceTrigger
на SelectedValue
привязка к PropertyChanged
исправил. Я не знаю почему, но для меня источник данных не обновлялся, пока я не внес это изменение.
<ComboBox
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UpdateTypesManager:MainWindow}}, Path=CardinalityTypes}"
DisplayMemberPath="CardinalityType"
SelectedValue="{Binding CardinalityTypeId, UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="Id" />
я смог заставить это работать. Но я устроил все немного по-другому.
- Я создал ViewModel, чтобы действовать как контракт с представлением.
- я привязан к ComboBox.Свойство SelectedItem вместо ComboBox.SelectedValue Свойство
поскольку я не знал, что такое ваш источник данных, я создал свой собственный, чтобы имитировать основную проблему: правильная привязка comboBox в WPF DataGrid.
вот состав моего Смотреть Модель:
public class RootViewModel
{
public List<State> USStates { get; set; }
public List<Customer> Customers { get; set; }
public ViewModel()
{
Customers = new List<Customer>();
Customers.Add(new Customer() { FirstName = "John", LastName = "Smith", State = new State() { ShortName = "IL" } });
Customers.Add(new Customer() { FirstName = "John", LastName = "Doe", State = new State() { ShortName = "OH" } });
Customers.Add(new Customer() { FirstName = "Sally", LastName = "Smith", State = new State() { ShortName = "IN" } });
USStates = new List<State>();
USStates.Add(new State() { ShortName = "OH" });
USStates.Add(new State() { ShortName = "IL" });
USStates.Add(new State() { ShortName = "IN" });
}
}
public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
public State State { get; set; }
}
public class State
{
public string ShortName { get; set; }
public State()
{
ShortName = string.Empty;
}
public override bool Equals(object obj)
{
if (obj is State)
{
State otherState = obj as State;
return ShortName.Equals(otherState.ShortName);
}
else
{
return false;
}
}
}
прежде чем мы начнем, я установил DataContext моего окна как экземпляр моей правильно построенной RootViewModel.
<tk:DataGrid ItemsSource="{Binding Customers}" AutoGenerateColumns="False">
<tk:DataGrid.Columns>
<tk:DataGridTemplateColumn Header="State">
<tk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=State.ShortName, Mode=TwoWay}" />
</DataTemplate>
</tk:DataGridTemplateColumn.CellTemplate>
<tk:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox
x:Name="cboDonationPurpose"
SelectedItem="{Binding Path=State, Mode=TwoWay}"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window},Mode=FindAncestor}, Path=DataContext.USStates}"
DisplayMemberPath="ShortName"
SelectedValuePath="ShortName" />
</DataTemplate>
</tk:DataGridTemplateColumn.CellEditingTemplate>
</tk:DataGridTemplateColumn>
</tk:DataGrid.Columns>
</tk:DataGrid>
для правильной привязки SelectedItem мне нужно убедиться, что я переопределил метод Equals на моей сущности, так как под капотом WPF использует этот метод для определения того, кто является SelectedItem или нет. Я думаю, что это была принципиально ваша проблема с самого начала, которая заставила вас попытаться привязать к SelectedValue вместо элемент.