I have listview with textbox in one column. Listview is bound to IEnumerable collection. When I edit text in textboxes and click OK, bound collection has only original values.
I Snooped listview and see changes made in textboxes appear in listviewitem's objects while listview is on screen, but in OK button handler they all gone.Here is window's xaml and code-behind (payee is result of linq-to-xml query produced by window's caller):
<Grid>
<ListView HorizontalAlignment="Stretch" Margin="0,38,0,0" Name="lvPayee"
VerticalAlignment="Stretch" GridViewColumnHeader.Click="lvPayee_Click" Background="AliceBlue">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="Listed" Width="60">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Margin="15,0,0,0" IsChecked="{Binding Listed}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Payee" Width="425">
<GridViewColumn.CellTemplate>
<DataTemplate DataType="{x:Type TextBox}">
<TextBox Width="420" Text="{Binding Name}" Background="Transparent"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Use Count" Width="80" DisplayMemberBinding="{Binding UseCount}"/>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
<CheckBox Content="Listed Only" Height="27" HorizontalAlignment="Left" Margin="57,12,0,0" Name="cbListedOnly" VerticalAlignment="Top" Width="129" IsChecked="True" Click="Listed_Clicked" />
<Button Content="OK" Height="27" HorizontalAlignment="Left" Margin="381,6,0,0" Name="btnOK" VerticalAlignment="Top" Width="89" Click="OK_Clicked" />
<Button Content="Cancel" Height="27" HorizontalAlignment="Left" Margin="493,6,0,0" Name="btnCancel" VerticalAlignment="Top" Width="80" IsCancel="True" />
</Grid>
public partial class PayeeManager : Window
{
private IEnumerable<Payee> payees = null;
private IEnumerable<Payee> payto = null;
private bool reverse = false;
private string lastColumn = "";
public PayeeManager(Window owner, IEnumerable<Payee> payees)
{
this.Owner = owner;
this.payees = payees;
InitializeComponent();
payto = from p in this.payees
where p.Listed == true
orderby p.Name
select p;
lvPayee.ItemsSource = payto;
}
public class Payee
{
public string Name { get; set; }
public int UseCount { get; set; }
public bool Listed { get; set; }
public string OldName { get; set; }
public bool OldListed { get; set; }
}
private void Listed_Clicked(object sender, RoutedEventArgs e)
{
payto = from p in this.payees
where cbListedOnly.IsChecked == true ? p.Listed == true : true
select p;
lvPayee.ItemsSource = payto;
}
private void lvPayee_Click(object sender, RoutedEventArgs e)
{
if (!(e.OriginalSource is GridViewColumnHeader)) return;
string header = (string)((GridViewColumnHeader)e.OriginalSource).Column.Header;
if (lastColumn != header)
{
lastColumn = header;
reverse = false;
}
else reverse = !reverse;
switch (header)
{
case "Listed":开发者_StackOverflow社区
payto = from p in this.payees
where cbListedOnly.IsChecked == true ? p.Listed == true : 1 == 1
orderby p.Listed
select p;
break;
case "Payee":
payto = from p in this.payees
where cbListedOnly.IsChecked == true ? p.Listed == true : 1 == 1
orderby p.Name
select p;
break;
case "Use Count":
payto = from p in this.payees
where cbListedOnly.IsChecked == true ? p.Listed == true : 1 == 1
orderby p.UseCount
select p;
break;
default:
return;
}
if (reverse) payto = payto.Reverse();
lvPayee.ItemsSource = payto;
}
private void OK_Clicked(object sender, RoutedEventArgs e)
{
DialogResult = true;
}
}
I found the problem. I used as listview's ItemSource Linq query, and it was refreshed when accessed, loosing changes. I changed ItemSource to List, using ToList() on query and it works now.
精彩评论