Xamarin ListView with Binding in xaml to C# code - c#

How do I convert the following ListView with ItemTemplate and Binding in the xaml file to equivalent C# code:
<ListView VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"
ItemsSource="{Binding A}" ItemSelected="OnClick">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding b}" Detail="{Binding c}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Try something like this:
ListView lv = new ListView();
lv.HorizontalOptions = LayoutOptions.FillAndExpand;
lv.VerticalOptions = LayoutOptions.FillAndExpand;
lv.SetBinding(ListView.ItemsSourceProperty, new Binding("A"));
lv.ItemSelected += (sender, args) =>
{
onclick(sender, args);
}; //Remember to remove this event handler on dispoing of the page;
DataTemplate dt = new DataTemplate(typeof(TextCell));
dt.SetBinding(TextCell.TextProperty, new Binding("b"));
dt.SetBinding(TextCell.DetailProperty, new Binding("c"));
lv.ItemTemplate = dt;
For more complex Datatemplates do:
DataTemplate dt = new DataTemplate(() =>
{
var button = new Button();
button.SetBinding(Button.TextProperty, new Binding("Name"));
return new ViewCell { View = button };
});

Related

how to move horizontally using ImageButton in C# xamarin forms android?

I'm trying to move horizontally using ImageButtons in C# xamarin forms android.
My app looks like this:
What I want to do if it's possible is move horizontally using those ImageButtons. I'd like to touch the ImageButton and go through each StackLayout that my code generate dynamically. But I don't know how could I do that.
I will let my code here:
code page.xaml:
<AbsoluteLayout>
<ScrollView HorizontalScrollBarVisibility="Never" Orientation="Horizontal" HorizontalOptions="Center">
<StackLayout x:Name="imgs" Orientation="Horizontal" HorizontalOptions="Center">
</StackLayout>
</ScrollView>
<ImageButton x:Name="btnLeft" Clicked="btnMoveLeft" Source="drawable/left.png" WidthRequest="50" HeightRequest="50" AbsoluteLayout.LayoutBounds="0.009,0.5,100,100" AbsoluteLayout.LayoutFlags="PositionProportional"></ImageButton>
<ImageButton x:Name="btnRight" Clicked="btnMoveRight" Source="drawable/right.png" WidthRequest="50" HeightRequest="50" AbsoluteLayout.LayoutBounds="0.95,0.5,100,100" AbsoluteLayout.LayoutFlags="PositionProportional"></ImageButton>
</AbsoluteLayout>
code Page.xaml.cs:
private void btnMoveLeft(object sender, EventArgs e)
{
}
private void btnMoveRight(object sender, EventArgs e)
{
}
public void generateImg(MediaFile file2)
{
StackLayout stackLayout = new StackLayout();
stackLayout.Orientation = StackOrientation.Vertical;
StackLayout stackLayoutMinimo = new StackLayout();
Image im = new Image();
im.ClassId = contador.ToString();
im.Source = ImageSource.FromFile(file2.Path);
im.HeightRequest = 600;
im.WidthRequest = 400;
im.MinimumHeightRequest = 600;
im.MinimumWidthRequest = 400;
im.VerticalOptions = LayoutOptions.End;
im.HorizontalOptions = LayoutOptions.End;
im.Aspect = Aspect.AspectFill;
stackLayout.Children.Add(im);
Button deleteButton = new Button();
deleteButton.ClassId = contador.ToString();
deleteButton.Text = "Borrar imagen";
deleteButton.VerticalOptions = LayoutOptions.CenterAndExpand;
deleteButton.HorizontalOptions = LayoutOptions.Center;
deleteButton.MinimumWidthRequest = 100;
deleteButton.ClassId = contador.ToString();
deleteButton.AutomationId = contador.ToString();
deleteButton.Clicked += async (sender, args) => {
listDelete.Add(Convert.ToInt32(deleteButton.ClassId));
stackLayout.Children.Remove(im);
stackLayout.Children.Remove(deleteButton);
};
stackLayout.Children.Add(deleteButton);
imgs.Children.Add(stackLayout);
}
I hope someone can guide me. Thank you very much!
Just as Jason said, CarouselView is more suitable than ScrollView in your situation.
I made a demo by using CarouselView and you can refer to this.
Here is the code in Mainpage.Xaml:
<CarouselView ItemsSource="{Binding Photos}">
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame HasShadow="True"
BorderColor="Gray"
CornerRadius="10"
Margin="25"
HeightRequest="350"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand">
<StackLayout>
<Label Text="{Binding Name}"
FontAttributes="Bold"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Image Source="{Binding Url}"></Image>
<Label Text="{Binding Location}"
HorizontalOptions="Center" />
<Label Text="{Binding Details}"
FontAttributes="Italic"
HorizontalOptions="Center"
MaxLines="5"
LineBreakMode="TailTruncation" />
<Button Text="Click"/>
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
Here is the code in Mainpage.Xaml.cs:
public MainPage()
{
InitializeComponent();
this.BindingContext = new MyViewModel();
}
Here is the code in MyViewModel.cs and you can add data to it:
public class MyViewModel
{
public ObservableCollection<Photo> Photos { get; set; }
public MyViewModel()
{
Photos = new ObservableCollection<Photo>();
Photos.Add(new Photo() { Name = "Photos", Details= "Photos", Location= "Photos", Url= "Photos" });
Photos.Add(new Photo() { Name = "Photos", Details = "Photos", Location = "Photos", Url = "Photos" });
Photos.Add(new Photo() { Name = "Photos", Details = "Photos", Location = "Photos", Url = "Photos" });
}
}
Here is the code in Photo.cs:
public class Photo
{
public string Name { get; set; }
public string Location { get; set; }
public string Details { get; set; }
public string Url { get; set; }
}
SOLUTION
Finally, I use a CarouselView, it worked perfectly. With this code I resolved my problem. I left my code here. Maybe it helps someone.
code page.xaml:
<AbsoluteLayout>
<StackLayout Padding="5">
<CarouselView x:Name="carousel" HeightRequest="600" IndicatorView="{x:Reference contImgs}">
<CarouselView.ItemTemplate>
<DataTemplate>
<Image x:Name="activeImg" Source="{Binding Source}" Aspect="AspectFill"></Image>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
<IndicatorView x:Name="contImgs" IndicatorColor="#bbb" SelectedIndicatorColor="#000" IndicatorSize="12" IndicatorsShape="Circle"></IndicatorView>
</StackLayout>
<ImageButton Source="drawable/icon_trash.png" WidthRequest="100" Clicked="btnDeleteImg" HeightRequest="100" AbsoluteLayout.LayoutBounds="0.98,0.07,50,50" AbsoluteLayout.LayoutFlags="PositionProportional"></ImageButton>
<ImageButton x:Name="left" Clicked="btnMoveLeft" Source="drawable/left.png" WidthRequest="50" HeightRequest="50" AbsoluteLayout.LayoutBounds="0.009,0.5,100,100" AbsoluteLayout.LayoutFlags="PositionProportional"></ImageButton>
<ImageButton x:Name="right" Clicked="btnMoveRight" Source="drawable/right.png" WidthRequest="50" HeightRequest="50" AbsoluteLayout.LayoutBounds="0.95,0.5,100,100" AbsoluteLayout.LayoutFlags="PositionProportional"></ImageButton>
</AbsoluteLayout>
code Page.xaml.cs:
private List<Image> imgsCarrousel = new List<Image>();
public void generarImg (MediaFile file2)
{
StackLayout stackLayout = new StackLayout();
stackLayout.Orientation = StackOrientation.Vertical;
StackLayout stackLayoutMinimo = new StackLayout();
Image im = new Image();
im.ClassId = contador.ToString();
im.Source = ImageSource.FromFile(file2.Path);
im.HeightRequest = 600;
im.WidthRequest = 400;
im.MinimumHeightRequest = 600;
im.MinimumWidthRequest = 400;
im.VerticalOptions = LayoutOptions.End;
im.HorizontalOptions = LayoutOptions.End;
im.Aspect = Aspect.AspectFill;
stackLayout.Children.Add(im);
ImageButton deleteButton = new ImageButton();
deleteButton.ClassId = contador.ToString();
deleteButton.Source = "drawable/icon_trash.png";
deleteButton.HeightRequest = 50;
deleteButton.WidthRequest = 50;
deleteButton.VerticalOptions = LayoutOptions.CenterAndExpand;
deleteButton.HorizontalOptions = LayoutOptions.Center;
deleteButton.MinimumWidthRequest = 100;
deleteButton.ClassId = contador.ToString();
deleteButton.AutomationId = contador.ToString();
deleteButton.Clicked += async (sender, args) => {
listDelete.Add(Convert.ToInt32(deleteButton.ClassId));
stackLayout.Children.Remove(im);
stackLayout.Children.Remove(deleteButton);
};
stackLayout.Children.Add(deleteButton);
ImageButton imChica = new ImageButton();
imChica.ClassId = contador.ToString();
imChica.Source = ImageSource.FromFile(file2.Path);
imChica.HeightRequest = 100;
imChica.WidthRequest = 100;
imChica.MinimumHeightRequest = 100;
imChica.MinimumWidthRequest = 100;
imChica.VerticalOptions = LayoutOptions.End;
imChica.HorizontalOptions = LayoutOptions.End;
imChica.Aspect = Aspect.AspectFill;
imChica.Clicked += async (sender, args) => {
};
stackLayoutMinimo.Children.Add(imChica);
imgsMinimo.Children.Add(stackLayoutMinimo);
imgsCarrousel.Add(im);
}
Of course, finally i need this line to set the images in my Page.xaml.cs:
carousel.ItemsSource = imgsCarrousel;

Xamarin.Forms StackLayout with x:Name not being found when inside DataTemplate

The XAML file is as follows:
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WPapp.Views.Home"
x:Name="HomeHeader">
<ContentPage.ToolbarItems>
<ToolbarItem Text="Refresh"
x:Name="refreshButton"
Clicked="refreshButton_Clicked"/>
</ContentPage.ToolbarItems>
<ContentPage.Content>
<ScrollView>
<StackLayout Margin="10"
HorizontalOptions="Center"
VerticalOptions="FillAndExpand"
x:Name="HomeContainer">
<Label Text="Featured Posts"
FontSize="Title"
FontAttributes="Bold"
Margin="0, 20, 10, 0"/>
<CarouselView>
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout x:Name="FeaturedContainer"/>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
</StackLayout>
</ScrollView>
</ContentPage.Content>
</ContentPage>
With this line in the c# file,
FeaturedContainer.Children.Clear();
I am getting the following error:
Error CS0103: The name 'FeaturedContainer' does not exist in the current context (CS0103)
What am I doing wrong?
You can get current item by adding a name to :
<CarouselView x:Name="myCarouselView">
And then get the current visiable stacklayout:
private void Button_Clicked(object sender, EventArgs e)
{
ObservableCollection<View> views = myCarouselView.VisibleViews;
StackLayout st = views[0] as StackLayout;
st.Children.Clear();
//or
StackLayout st1 = myCarouselView.CurrentItem as StackLayout;
st1.Children.Clear();
}
Update:
add several stacklayouts inside the carousel view via c#
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
CarouselView carouselView = new CarouselView
{
ItemsLayout = (LinearItemsLayout)LinearItemsLayout.Horizontal
};
carouselView.ItemTemplate = new DataTemplate(typeof(CustomCell));
carouselView.ItemsSource = new string[]
{
"Baboon",
"Capuchin Monkey",
"Blue Monkey",
"Squirrel Monkey",
"Golden Lion Tamarin",
"Howler Monkey",
"Japanese Macaque"
};
Content = carouselView;
}
}
public class CustomCell : ContentView
{
public CustomCell()
{
//instantiate each of our views
var image = new Image();
StackLayout cellWrapper = new StackLayout();
StackLayout horizontalLayout = new StackLayout();
Label left = new Label();
Label right = new Label();
//set bindings
left.Text = "title";
right.Text = "title";
//Set properties for desired design
cellWrapper.BackgroundColor = Color.FromHex("#eee");
horizontalLayout.Orientation = StackOrientation.Horizontal;
right.HorizontalOptions = LayoutOptions.EndAndExpand;
left.TextColor = Color.FromHex("#f35e20");
right.TextColor = Color.FromHex("503026");
//add views to the view hierarchy
horizontalLayout.Children.Add(image);
horizontalLayout.Children.Add(left);
horizontalLayout.Children.Add(right);
cellWrapper.Children.Add(horizontalLayout);
this.Content = cellWrapper;
}
}

How to add Listbox Dynamically to Wrap panel at runtime by using Drag and Drop in WPF

This is my code, There is one listbox in right side, the listbox item is added to the another list box item inside the grid. The Grid is added dynamically by using the context menu. Till it is working fine. But now I want to move the whole list not list items, to the grid dynamically at runtime. Please anyone guide me to drag the whole list and placing the whole list to grid at runtime dynamically.
<Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<WrapPanel
x:Name="mainPanel"
Grid.Column="0"
Background="#F0F0F0"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<WrapPanel.ContextMenu>
<ContextMenu>
<MenuItem Click="MenuItem_Click" Header="Add Pabel" />
</ContextMenu>
</WrapPanel.ContextMenu>
</WrapPanel>
<ListBox
Name="memberCollection"
Grid.Column="1"
Width="150"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
PreviewMouseLeftButtonDown="memberCollection_PreviewMouseLeftButtonDown">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Label Name="Name" Content="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
Code Behind
ObservableCollection<Member> member = new ObservableCollection<Member>();
public MainWindow()
{
InitializeComponent();
member.Add(new Member { Name = "Karthick", ID = "20011", Address = "10, MainRoad, Chennai" });
member.Add(new Member { Name = "Suresh", ID = "20012", Address = "11, MainRoad, Madurai" });
member.Add(new Member { Name = "Arun", ID = "20013", Address = "12, MainRoad, Selam" });
member.Add(new Member { Name = "Gokul", ID = "20014", Address = "13, MainRoad, Coimbature" });
member.Add(new Member { Name = "Vishnu", ID = "20015", Address = "14, MainRoad, Goa" });
memberCollection.ItemsSource = member;
}
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
Grid panel = new Grid();
panel.MinHeight = 150;
panel.MinWidth = 150;
panel.Height = 150;
panel.Width = 150;
panel.Margin = new Thickness(15,15,0,10);
Grid gridDrop = new Grid()
{
Background = Brushes.White,
HorizontalAlignment = HorizontalAlignment.Stretch,
VerticalAlignment = VerticalAlignment.Stretch
};
gridDrop.Drop += grid_Drop;
var panelTemplate = new DataTemplate();
var stackPanel = new FrameworkElementFactory(typeof(StackPanel));
stackPanel.SetValue(StackPanel.OrientationProperty, Orientation.Vertical);
var name = new FrameworkElementFactory(typeof(Label));
name.SetBinding(Label.ContentProperty, new Binding("Name"));
var id = new FrameworkElementFactory(typeof(Label));
id.SetBinding(Label.ContentProperty, new Binding("ID"));
var address = new FrameworkElementFactory(typeof(Label));
address.SetBinding(Label.ContentProperty, new Binding("Address"));
stackPanel.AppendChild(name);
stackPanel.AppendChild(id);
stackPanel.AppendChild(address);
panelTemplate.VisualTree = stackPanel;
ListBox listBox = new ListBox()
{
AllowDrop = true,
ItemTemplate = panelTemplate
};
gridDrop.Children.Add(listBox);
panel.Children.Add(gridDrop);
mainPanel.Children.Add(panel);
DataContext = new Member();
}
private void memberCollection_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
object selectedMember = memberCollection.SelectedItem as Member;
if (selectedMember != null)
{
DragDrop.DoDragDrop(memberCollection, selectedMember, DragDropEffects.Move);
}
}
private void grid_Drop(object sender, RoutedEventArgs e)
{
ListBox listContent = e.Source as ListBox;
if (listContent != null)
Console.WriteLine("", Grid.GetColumn(listContent), Grid.GetRow(listContent));
DataObject item = (((DragEventArgs)e).Data) as DataObject;
object Target = ((Grid)(sender)).DataContext;
if (Target != null)
{
object listItem = item.GetData(Target.GetType());
listContent.Items.Add(listItem);
}
}
If you only want to move the whole list and create a tile for each Member, then this is one way to go:
First of all, you should simplify your template and put it in the XAML.
XAML is much more efficient at handling any kind of template than the code behind
For your left mainPanel:
<ItemsControl x:Name="mainPanel" Grid.Column="0" ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Background="#F0F0F0" AllowDrop="True" Drop="mainPanel_Drop">
<WrapPanel.ContextMenu>
<ContextMenu>
<MenuItem Click="MenuItem_Click" Header="Add Panel" />
</ContextMenu>
</WrapPanel.ContextMenu>
</WrapPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" Background="White" AllowDrop="True" Margin="15,15,0,10" Width="150" MinWidth="150" Height="150" MinHeight="150">
<Label Content="{Binding Name}"/>
<Label Content="{Binding ID}"/>
<Label Content="{Binding Address}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
And for your list (no much changes)
<ListBox
Name="memberCollection"
Grid.Column="1"
Width="150"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ItemsSource="{Binding}"
PreviewMouseLeftButtonDown="memberCollection_PreviewMouseLeftButtonDown">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Label Name="memberName" Content="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I added two ObservableCollection to manage the Data
ObservableCollection<Member> member = new ObservableCollection<Member>();
ObservableCollection<Member> mainPanelMembers = new ObservableCollection<Member>();
public MainWindow()
{
InitializeComponent();
member.Add(new Member { Name = "Karthick", ID = "20011", Address = "10, MainRoad, Chennai" });
member.Add(new Member { Name = "Suresh", ID = "20012", Address = "11, MainRoad, Madurai" });
member.Add(new Member { Name = "Arun", ID = "20013", Address = "12, MainRoad, Selam" });
member.Add(new Member { Name = "Gokul", ID = "20014", Address = "13, MainRoad, Coimbature" });
member.Add(new Member { Name = "Vishnu", ID = "20015", Address = "14, MainRoad, Goa" });
memberCollection.DataContext = member;
mainPanel.DataContext = mainPanelMembers;
}
Then, the creation of a new Tile is much much more simplier:
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
mainPanelMembers.Add(new Member());
}
If you want to copy the whole list, then you have to give the whole ObservableCollection to the DragDrop manager:
private void memberCollection_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
object collectionDataContext = memberCollection.DataContext;
if (collectionDataContext != null)
{
DataObject dragData = new DataObject("DataContext", collectionDataContext);
DragDrop.DoDragDrop(memberCollection, dragData, DragDropEffects.Move);
}
}
And when you drop it, you can simply add the Member one by one. You could also clear the collection before (but I didn't):
private void mainPanel_Drop(object sender, DragEventArgs e)
{
DataObject item = e.Data as DataObject;
object listItem = item.GetData("DataContext") as IEnumerable<Member>;
if (listItem != null)
{
foreach (Member member in (IEnumerable<Member>)listItem)
{
((ObservableCollection<Member>)mainPanel.DataContext).Add(member);
}
}
}
I'm not sure I understood very well what you wanted... I still don't know how you're using the Tile creation.
Let me know if you need to do something different.

How to update ObservableCollection?

I have folder with images, which I show in my ListBox. ObservableCollection stores that images. In my program users could crop selected image and after cropping save that image. Problem is that after saving the image my ObservableCollection is not updated (although OnPropertyChange event is rise) and shows the same image. Does anybody have the same problem?
EDIT
I have BindingManager where I place my observableCollection.
public class BindingsManager:INotifyPropertyChanged
{
private ObservableCollection<PhotoModel> _photoList;
public ObservableCollection<PhotoModel> PhotoList
{
get {return _photoList;}
set
{
_photoList = value;
OnPropertyChanged(nameof(PhotoList));
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
In Xaml file I bind source to PhotoList:
<ListView x:Name="PhotoListView" ItemsSource="{Binding PhotoList, UpdateSourceTrigger=PropertyChanged}">
After double click on image, image will be opened in new window where user can crop it and save to DefaultDestFolder which is tracking by FileSystemWatcher:
private void WatchDestinationFolder()
{
var watcher = new FileSystemWatcher
{
Path = BindingsManager.DefaultsManager.DefaultDestFolder,
NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size | NotifyFilters.LastAccess | NotifyFilters.LastWrite,
Filter = "*.*"
};
watcher.Changed += UpdatePhotoList;
watcher.EnableRaisingEvents = true;
}
And on change event i update my ObservableCollection but it doesn't work:
private void UpdatePhotoList()
{
var files = Directory.GetFiles(BindingsManager.DefaultsManager.DefaultDestFolder, "*.*");
BindingsManager.PhotoList = new ObservableCollection<PhotoModel>();
foreach (var file in files)
{
Application.Current.Dispatcher.Invoke((Action)(() =>
{
var fileInfo = new FileInfo(file);
BitmapImage img = new BitmapImage();
img.BeginInit();
img.CacheOption = BitmapCacheOption.OnLoad;
img.UriSource = new Uri(file, UriKind.Absolute);
img.EndInit();
BindingsManager.PhotoList.Add(new PhotoModel()
{
BitmapImage = img,
FullFileName = fileInfo.FullName,
ShortFileName = fileInfo.Name,
FileLastAccessTime = fileInfo.LastAccessTime,
FileSize = fileInfo.Length,
Width = (int)img.Width,
Height = (int)img.Height,
DirectoryName = fileInfo.DirectoryName,
FileCreationTime = fileInfo.CreationTime
});
}));
}
}
EDIT
<ScrollViewer Grid.Column="2">
<ListView x:Name="PhotoListView" BorderThickness="0"
ItemsSource="{Binding PhotoList, UpdateSourceTrigger=PropertyChanged}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<controls:Tile Style="{StaticResource TileStyle}">
<StackPanel Background="White" Width="190" Height="140" Orientation="Vertical">
<Image Margin="5" Width="180" Height="110" Stretch="Fill" Source="{Binding BitmapImage}"/>
<TextBlock Text="{Binding ShortFileName}" TextAlignment="Center" Height="20" FontStyle="Italic" FontWeight="ExtraLight" Foreground="Black"></TextBlock>
</StackPanel>
</controls:Tile>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<EventSetter Event="MouseDoubleClick" Handler="ItemMouseDoubleClick"></EventSetter>
<EventSetter Event="PreviewMouseLeftButtonUp" Handler="ItemMouseClick"></EventSetter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
</ScrollViewer>
I think binding isn't your main problem. You should check image caching. Try: Reloading an image in wpf

Silverlight Master/Detail's Situation

I have a DataGrid. The ItemsSource of this DataGrid is set in the Completed event of a WCF call.However, when adding a Detail Datagrid inside the master grids DataTemplate and naming it appropriately... Ineed to fill it master grids selection change event but my codebehind does not recognise the detail grid. I cant set the ItemsSource of grdDetail like I do with grdMaster.So how i can fill my detail datagrid ?
Xaml File
<Grid x:Name="LayoutRoot">
<sdk:DataGrid x:Name="dgCustList" AutoGenerateColumns="False" Background="Transparent" SelectionChanged="dgCustList_SelectionChanged">
<sdk:DataGrid.RowDetailsTemplate>
<DataTemplate>
<StackPanel x:Name="stkPanel">
<sdk:DataGrid x:Name="dgCustDetail" RowDetailsVisibilityMode="VisibleWhenSelected" AutoGenerateColumns="False" Background="Transparent"/>
</StackPanel>
</DataTemplate>
</sdk:DataGrid.RowDetailsTemplate>
</sdk:DataGrid>
<Grid.Projection>
<PlaneProjection x:Name="Projection"/>
</Grid.Projection>
</Grid>
And CodeBehind
public MusteriListe()
{
InitializeComponent();
var stb1 = new Storyboard { Duration = new Duration(TimeSpan.FromSeconds(1)), SpeedRatio = 3 };
var daY1 = new DoubleAnimation { From = 0.00, To = 90.00 };
Storyboard.SetTargetName(daY1, "Projection");
Storyboard.SetTargetProperty(daY1, new PropertyPath("RotationX"));
stb1.Children.Add(daY1);
this.Resources.Add("EndOfPage", stb1);
var stb = new Storyboard();
stb.Duration = new Duration(TimeSpan.FromSeconds(1));
stb.SpeedRatio = 3;
var daY = new DoubleAnimation { From = -90.00, To = 0.00 };
Storyboard.SetTargetName(daY, "Projection");
Storyboard.SetTargetProperty(daY, new PropertyPath("RotationX"));
stb.Children.Add(daY);
Resources.Add("StartOfPage", stb);
dgCustList.Columns.Add(new DataGridTextColumn
{
Header = "ID",
Binding = new Binding("CustomerID")
});
dgCustList.Columns.Add(new DataGridTextColumn
{
Header = "Müşteri Ad",
Binding = new Binding("CustomerName")
});
dgCustList.Columns.Add(new DataGridTextColumn
{
Header = "Müşteri Soyad",
Binding = new Binding("CustomerSurname")
});
dgCustList.Columns.Add(new DataGridTextColumn
{
Header = "Müşteri Tel",
Binding = new Binding("CustomerPhone")
});
LoadGrid();
}
private void LoadGrid()
{
var client = new EczServiceClient();
client.CustomerInfoCompleted += client_CustomerInfoCompleted;
client.CustomerInfoAsync();
}
void client_CustomerInfoCompleted(object sender, CustomerInfoCompletedEventArgs e)
{
dgCustList.ItemsSource = e.Result;
}
private void dgCustList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var customer = dgCustList.SelectedItem as CustomerInfo;
if (customer == null) return;
var client = new EczServiceClient();
client.CustomerDetailCompleted += client_CustomerDetailCompleted;
client.CustomerDetailAsync(customer.CustomerID);
}
void client_CustomerDetailCompleted(object sender, CustomerDetailCompletedEventArgs e)
{
IN HERE I WANT TO FILL DATAGRID LIKE MASTER GRID BUT ITS NOT LET ME ( dgCustDetail.ItemSource = e.Result)
}
You did NOTdefine binding for you detail data grid and you set the autogenerate columns to false. You need to define the binding either in XAML or in code behind before the client_CustomerDetailCompleted event fires. Simply setting the item source alone won't work because the detail datagrid does not contain columns. This is where MVVM pattern comes in handy.

Categories