For my first Silverlight app, I've written a program that sends user-supplied search strings to the Flickr REST API and displays the results in a DataGrid
. Said grid is defined like so:
<data:DataGrid x:Name="PhotoGrid" AutoGenerateColumns="False">
<data:DataGrid.Columns>
<data:DataGridTextColumn Header="Photo Title" Binding="{Binding Title}" CanUserSort="True" CanUserReorder="True" CanUserResize="True" IsReadOnly="True" />
<data:DataGridTemplateColumn Header="Photo" SortMemberPath="ImageUrl">
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<TextBlock Text="Click here to show image" MouseLeftButtonUp="ShowPhoto"/>
<Image Visibility="Collapsed" MouseLeftButtonUp="HidePhoto"/>
</StackPanel>
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>
</data:DataGrid.Columns>
</data:DataGrid>
It's a simple two-column table. The first column contains the title of the photo, while the second contains the text 'Click here to show image'. Clicks there call ShowPhoto()
, which updates the Image
element开发者_开发问答's Source
property with a BitmapImage
derived from the URI of the Flickr photo, and sets the image's visibility to Visible
. Clicking on the image thus revealed hides it again. All of this was easy to implement and works perfectly.
But whenever I click on one of the column headers to sort by that column, the cells that I've updated in this way do not change. The rest of the DataGrid
is resorted and updated appropriately, but those cells remain behind, detached from the rest of their row. This is very strange, and not at all what I want.
What am I doing wrong? Should I be freshening the DataGrid
somehow in response to the sort event, and if so how? Or if I'm not supposed to be messing with the contents of the grid directly, what's the right way to get the behavior I want?
I think you should Bind the Image Source to an element in a collection and update that element in the code behind instead of modifying the element directly. Make sure your property generates a property changed event and your main object implements INotifyPropertyChanged
public string Url
{
get { return url; }
set
{
url = value;
NotifyPropertyChanged("Url");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
********************* Adding the code to clarify *********************** You should probably reset the row height when you hide an image. I don't see any issues with smearing and images in the background. Here is my code
<DataTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<Button Click="ShowHidePhoto" Content="show/hide" Tag="{Binding}"/>
<Image Visibility="{Binding Visible}" Source="{Binding Url}" MouseLeftButtonUp="OnImageClick"/>
</StackPanel>
</DataTemplate>
code behind
private void ShowHidePhoto(object sender, RoutedEventArgs e)
{
DataHolder dh = (DataHolder)((Button)sender).Tag;
dh.Visible = dh.Visible == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
// reset height here....
}
Did you try DataGrid.items.refresh after sorting ? Might be too easy for an answer, but it sometime solve problems I had with Datagrid...
精彩评论