<ListBox Name="listBoxButtons"
Height="700">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Background="{StaticResource PhoneAccentBrush}"
Name="border"
Width="432" Height="62"
Margin="6" Padding="12,0,0,6">
<TextBlock Text="{Binding}"
Foreground="#FFFFFF" FontSize="26.667"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
FontFamily="{StaticResource PhoneFontFamilySemiBold}"/>
<Border.Projection>
<PlaneProjection RotationX="-60"/>
</Border.Projection>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Code:
private void ShowAnim()
{
IEasingFunction quadraticEase = new QuadraticEase { EasingMode = EasingMode.EaseOut };
Storyboard _swivelShow = new Storyboard();
foreach (var item in this.listBoxButtons.Items)
{
UIElement container = listBoxButtons.ItemContainerGenerator.ContainerFromItem(item) as UIElement;
if (container != null)
{
Border content = VisualTreeHelper.GetChild(container, 0) as Border;
if (content != null)
{
DoubleAnimationUsingKeyFrames showAnimation = new DoubleAnimationUsingKeyFrames();
EasingDoubleKeyFrame showKeyFrame1 = new EasingDoubleKeyFrame();
showKeyFrame1.KeyTime = TimeSpan.FromMilliseconds(0);
showKeyFrame1.Value = -60;
showKeyFrame1.EasingFunction = quadraticEase;
EasingDoubleKeyFrame showKeyFrame2 = new EasingDoubleKeyFrame();
showKeyFrame2.KeyTime = TimeSpan.FromMilliseconds(85);
showKeyFrame2.Value = 0;
showKeyFrame2.EasingFunction = quadraticEase;
showAnimation.KeyFrames.Add(showKeyFrame1);
showAnimation.KeyFrames.Add(showKeyFrame2);
Storyboard.SetTargetProperty(showAnimation, new PropertyPath(PlaneProjection.RotationXProperty));
Storyboard.SetTarget(showAnimation, content.Projection);
_swivelShow.Children.Add(showAnimation);
}
}
}
_swivelShow.Begin();
}
But: Storyboard.SetTarget(showAnimation, content.Projection) throws an Exception. The content.Projection is null. How could that happen?
You are looking at the wrong Border element. The hierarchy of the item container in your case is like Border -> ContentControl -> ContentPresenter -> Border (this is yours). So you have to go deeper down the child hierarchy of your container to find the border you want.
The following code searches the children of an UIElement recursively and gives some debug output so you can see how deep it goes. It will stop when it finds a control named "border":
private UIElement GetMyBorder(UIElement container)
{
if (container is FrameworkElement && ((FrameworkElement)container).Name == "border")
return container;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(container); i++)
{
var child = (FrameworkElement)VisualTreeHelper.GetChild(container, i);
System.Diagnostics.Debug.WriteLine("Found child "+ child.ToString());
System.Diagnostics.Debug.WriteLine("Going one level deeper...");
UIElement foundElement = GetMyBorder(child);
if (foundElement != null)
return foundElement;
}
return null;
}
To use it:
Border content = (Border)GetMyBorder(container);
Related
How can I add many Button to the grid for the first Item and and textbox to another grid in the second item dynamically?
NOT XAML
Ican't find name GridItem - name not exist in code behind :(
I tried to find Visual Tree Helper :(
PivotItem pivotVHT = (PivotItem)mainSecondPivot.SelectedItem;
foreach (var element in VisualTreeHelper.FindElementsInHostCoordinates(new Rect(20, 0, 480, 700), pivotVHT))
{
if (element is TextBlock)
{
Debug.WriteLine("{0}", ((TextBlock)element).Text);
TextBlock test = ((TextBlock)element);
test.Text = "TEST";
}
}
VisualTreeHelper changing the text only mainFirstPivot, visual tree helper does not see mainSecondPivot
XAML:
<controls:Pivot Title="Photo Gallery" Name="mainSecondPivot" >
<controls:Pivot.HeaderTemplate>
<DataTemplate>
<Grid
x:Name="PivitGrid"
>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Image
Name="PivotImageGalery"
Source="{Binding imgSrc}"
>
</Image>
<TextBlock
x:Name="TextBlockPivot"
Text="{Binding textBlockPivotName}"
>
</TextBlock>
</Grid>
</DataTemplate>
</controls:Pivot.HeaderTemplate>
<controls:Pivot.ItemTemplate>
<DataTemplate>
<ScrollViewer
Name="SVName"
Width="Auto"
VerticalScrollBarVisibility ="Hidden"
HorizontalScrollBarVisibility="Disabled"
>
<Grid
x:Name="GridItem"
>
**HERE**
</Grid>
</ScrollViewer>
</DataTemplate>
</controls:Pivot.ItemTemplate>
</controls:Pivot>
C#
public static class SelectedIndex
{
public static int SelectedIndexInt = 0;// OR SOME NUMBER
}
public class IListPivot
{
public ImageSource imgSrc { get; set; }
public String textBlockPivotName { get; set; }
}
public secondPage()
{
InitializeComponent();
IList<IListPivot> PivotList = new List<IListPivot>();
for (z = 0; z <= 7; z++)
{
PivotList.Add(new IListPivot()
{
imgSrc = new System.Windows.Media.Imaging.BitmapImage(new Uri("URI", UriKind.Relative)),
textBlockPivotName = "TEXT"
});
}
mainSecondPivot.ItemsSource = PivotList;
mainSecondPivot.Loaded += new RoutedEventHandler (PivotLoaded);
mainSecondPivot.SelectedIndex = SelectedIndex.SelectedIndexInt
}
public void PivotLoaded(object sender, EventArgs e)
{
PivotItem pivotItemVHT = (PivotItem)mainSecondPivot.ItemContainerGenerator.ContainerFromIndex(SelectedIndex.SelectedIndexInt);
var root = VisualTreeHelper.GetChild(((VisualTreeHelper.GetChild(pivotItemVHT, 0) as Grid).Children[0] as ContentPresenter), 0) as FrameworkElement;
Debug.WriteLine(" root " + root);
Debug.WriteLine(" root Name " + root.Name);
ScrollViewer scr = (ScrollViewer)root;
TextBox BoxText1 = new TextBox();
BoxText1.Text = a.ToString();
scr.Content = BoxText1;
}
add only to one from everyone items
HELP
Here is how to retrieve a named element from inside a PivotItem:
public FrameworkElement GetPivotElement(int pivotIndex, string name)
{
var pivot = mainSecondPivot.ItemContainerGenerator.ContainerFromIndex(pivotIndex);
var root = VisualTreeHelper.GetChild(((VisualTreeHelper.GetChild(pivot, 0) as Grid).Children[0] as ContentPresenter), 0) as FrameworkElement;
return root.FindName(name);
}
I'm trying to display the movie dates for movies than are going to screen today. I have been reading different threads the whole day, buy I can´t get the webRequest to work.
Basically I had working code with webClient, but I wanted the UI to be responsive so I decided to use httpWebRequest to keep the xml parsing off the UI thread.
public partial class MainPage : PhoneApplicationPage {
public MainPage() {
InitializeComponent();
}
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e) {
DoHttpWebRequest();
}
private void DoHttpWebRequest() {
string url = "http://www.cinamon.ee/rss/schedule/1001.xml";
var request = HttpWebRequest.Create(url);
var result = (IAsyncResult)request.BeginGetResponse(ResponseCallback, request);
}
private void ResponseCallback(IAsyncResult result) {
var request = (HttpWebRequest)result.AsyncState;
var response = request.EndGetResponse(result);
using (var stream = response.GetResponseStream()) {
XDocument scheduleXml = XDocument.Load(stream);
var todayMovies = from query in scheduleXml.Descendants("schedule").Descendants("shows").Descendants("show")
where DateTime.Parse(query.Element("showDateTime").Value).Date.Equals(DateTime.Now.Date) &&
DateTime.Parse(query.Element("showDateTime").Value).TimeOfDay.CompareTo(DateTime.Now.TimeOfDay) > 0
select new Movie() {
MoviePicture = new BitmapImage(new Uri((string)query.Element("images").Element("imageType2").Value, UriKind.RelativeOrAbsolute)),
MovieName = (string)query.Element("title"),
MovieId = (string)query.Element("movieId"),
MovieSoonest = DateTime.Parse(query.Element("showDateTime").Value).ToString("H:mm")
};
// Removing duplicate movies from list.
List<Movie> todayList = todayMovies.ToList();
IEnumerable<Movie> noDuplicates3 = todayList.Distinct(new MovieComparer());
// Adding to the UI
Dispatcher.BeginInvoke(() => {
todayBox.ItemsSource = noDuplicates.ToList();
});
}
}
}
Does anyone have an idea as to what is wrong by looking at this code?
Thank you in advance
EDIT. This is the link I based my solution on - http://social.msdn.microsoft.com/Forums/en-US/windowsphone7series/thread/594e1422-3b69-4cd2-a09b-fb500d5eb1d8
EDIT2. My Mainpage.xaml
<StackPanel x:Name="TodayPanel" Grid.Row="1" Margin="10,5,10,10" Orientation="Horizontal" Height="580" Background="#90000000" >
<ListBox x:Name="todayBox">
<ListBox.ItemTemplate>
<DataTemplate>
<HyperlinkButton x:Name="hyperLinkButton" Style="{StaticResource HyperlinkButtonStyle1}" CommandParameter="{Binding MovieId}" Tap="hyperLinkButton_Tap">
<HyperlinkButton.Content>
<StackPanel Margin="10" Grid.Row="1" Orientation="Horizontal">
<Image Source="{Binding MoviePicture}" />
<StackPanel Margin="10" Grid.Row="1" Orientation="Vertical">
<TextBlock TextWrapping="Wrap" Margin="10, 5, 10, 5" Width="200" FontFamily="Trebuchet MS" Foreground="Orange" VerticalAlignment="Top">
<Run Text="{Binding MovieName}"/>
<LineBreak></LineBreak>
</TextBlock>
<TextBlock TextWrapping="Wrap" Width="200" FontFamily="Trebuchet MS" Foreground="White" VerticalAlignment="Bottom">
<Run Text="Järgmine seanss: "/>
<LineBreak></LineBreak>
<Run Text="{Binding MovieSoonest}"/>
</TextBlock>
</StackPanel>
</StackPanel>
</HyperlinkButton.Content>
</HyperlinkButton>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
And my edited code behind.
private void DoHttpWebRequest() {
string url = "http://www.cinamon.ee/rss/schedule/1001.xml";
var request = HttpWebRequest.Create(url);
var result = (IAsyncResult)request.BeginGetResponse(ResponseCallback, request);
}
private void ResponseCallback(IAsyncResult result) {
var request = (HttpWebRequest)result.AsyncState;
var response = request.EndGetResponse(result);
// Adding to the UI
Dispatcher.BeginInvoke(() => {
IEnumerable<Movie> todayMovies;
using (var stream = response.GetResponseStream()) {
XDocument scheduleXml = XDocument.Load(stream);
todayMovies = from query in scheduleXml.Descendants("schedule").Descendants("shows").Descendants("show")
where DateTime.Parse(query.Element("showDateTime").Value).Date.Equals(DateTime.Now.Date) &&
DateTime.Parse(query.Element("showDateTime").Value).TimeOfDay.CompareTo(DateTime.Now.TimeOfDay) > 0
select new Movie() {
MoviePicture = new BitmapImage(new Uri((string)query.Element("images").Element("imageType2").Value, UriKind.RelativeOrAbsolute)),
MovieName = (string)query.Element("title"),
MovieId = (string)query.Element("movieId"),
MovieSoonest = DateTime.Parse(query.Element("showDateTime").Value).ToString("H:mm")
};
}
var todayList = todayMovies.ToList();
//IEnumerable<Movie> noDuplicates = movieList.Distinct(new MovieComparer());
todayBox.ItemsSource = todayList.ToList();
});
I tried out your code and getting UnauthorizedAccessException. By changing Dispactcher.Begininvoke delegate's scope it works as follow:
private void ResponseCallback(IAsyncResult result){
var request = (HttpWebRequest) result.AsyncState;
var response = request.EndGetResponse(result);
// Adding to the UI
Dispatcher.BeginInvoke(() =>
{
IEnumerable<Movie> todayMovies;
using (var stream = response.GetResponseStream())
{
XDocument scheduleXml = XDocument.Load(stream);
todayMovies =
from query in scheduleXml.Descendants("schedule").Descendants("shows").Descendants("show")
where DateTime.Parse(query.Element("showDateTime").Value).Date.Equals(DateTime.Now.Date) &&
DateTime.Parse(query.Element("showDateTime").Value).TimeOfDay.CompareTo(DateTime.Now.TimeOfDay) >
0
select new Movie()
{
MoviePicture =
new BitmapImage(
new Uri((string) query.Element("images").Element("imageType2").Value,
UriKind.RelativeOrAbsolute)),
MovieName = (string) query.Element("title"),
MovieId = (string) query.Element("movieId"),
MovieSoonest = DateTime.Parse(query.Element("showDateTime").Value).ToString("H:mm")
};
}
// Removing duplicate movies from list.
var todayList = todayMovies.ToList();
//IEnumerable<Movie> noDuplicates3 = todayList.Distinct(new MovieComparer());
todayBox.ItemsSource = todayList.ToList();
});
}
However you may use RestSharp library (you may find it in Nuget) in order to make it easier. Check following code:
public void RestSample(){
var client = new RestClient
{
BaseUrl = "http://www.cinamon.ee/"
};
var request = new RestRequest
{
Resource = "rss/schedule/1001.xml"
};
client.ExecuteAsync(request, (a) =>
{
if (a.StatusCode == HttpStatusCode.OK)
{
var scheduleXml = XDocument.Parse(a.Content);
var todayMovies = from query in scheduleXml.Descendants("schedule").Descendants("shows").Descendants("show")
where DateTime.Parse(query.Element("showDateTime").Value).Date.Equals(DateTime.Now.Date) &&
DateTime.Parse(query.Element("showDateTime").Value).TimeOfDay.CompareTo(DateTime.Now.TimeOfDay) > 0
select new Movie()
{
MoviePicture = new BitmapImage(new Uri((string)query.Element("images").Element("imageType2").Value, UriKind.RelativeOrAbsolute)),
MovieName = (string)query.Element("title"),
MovieId = (string)query.Element("movieId"),
MovieSoonest = DateTime.Parse(query.Element("showDateTime").Value).ToString("H:mm")
};
// Removing duplicate movies from list.
List<Movie> todayList = todayMovies.ToList();
//IEnumerable<Movie> noDuplicates = todayList.Distinct(new MovieComparer());
// Adding to the UI
Dispatcher.BeginInvoke(() =>
{
todayBox.ItemsSource = todayList.ToList();
});
}
else
{
//error
}
});
}
Try it out and let us know...
EDITED: xaml.cs datatemplate:
<StackPanel x:Name="TodayPanel" Grid.Row="1" Margin="10,5,0,10" Orientation="Horizontal" Height="580" Background="#90000000" >
<ListBox x:Name="todayBox" Width="468">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="10" Orientation="Horizontal">
<Image Source="{Binding MoviePicture, FallbackValue=http://www.cinamon.ee/visinternetticketing/images/movies/NowShowingComingSoon/HungerGames.jpg}" />
<StackPanel Margin="10" Grid.Row="1" Orientation="Vertical">
<TextBlock TextWrapping="Wrap" Margin="10, 5, 10, 5" FontFamily="Trebuchet MS" Foreground="Orange" VerticalAlignment="Top" Text="{Binding MovieName}"/>
<TextBlock TextWrapping="Wrap" FontFamily="Trebuchet MS" Foreground="White" VerticalAlignment="Bottom" Text="{Binding MovieSoonest}"/>
</StackPanel>
<HyperlinkButton x:Name="hyperLinkButton" CommandParameter="{Binding MovieId}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
RECALL Change MovePicture Property from BitmapImage to string.
I need to create a new ListBox based on items that are selected (checked). The following code actually worked if I only had like 20 items on the ListBox, but adding more items make it crash. Can anybody know how to make it work, or have a different aproach? Is there a limite for looping through a listBox?
// worked fine for 20 items,
// but my actual list contems 95 items...
private void btnCreateNewList_Click(object sender, RoutedEventArgs e)
{
int totalItemsCB = ListCheckBoxVocabulary.Items.Count;
for (int ii = 0; ii < totalItemsCB-1; ii++)
{
ListBoxItem item = this.ListCheckBoxVocabulary.ItemContainerGenerator.ContainerFromIndex(ii) as ListBoxItem;
CheckBox thisCheckBox = FindFirstElementInVisualTree<CheckBox>(item);
if (thisCheckBox.IsChecked == true)
{
dataPlayListSource.Add(new SampleData() { Text = thisCheckBox.Content.ToString() + " | " + ii });
// this.PlayListCheckBoxVocabulary.UpdateLayout();
this.PlayListCheckBoxVocabulary.ItemsSource = dataPlayListSource;
}
}
}
private T FindFirstElementInVisualTree<T>(DependencyObject parentElement) where T : DependencyObject
{
var count = VisualTreeHelper.GetChildrenCount(parentElement);
if (count == 0)
return null;
for (int i = 0; i < count; i++)
{
var child = VisualTreeHelper.GetChild(parentElement, i);
if (child != null && child is T)
{
return (T)child;
}
else
{
var result = FindFirstElementInVisualTree<T>(child);
if (result != null)
return result;
}
}
return null;
}
and xaml:
<controls:PivotItem Header="Vocabulary" >
<ListBox x:Name="ListCheckBoxVocabulary" Margin="0,0,-12,0" ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<!--<StackPanel Margin="0,0,0,17" Width="432">-->
<CheckBox x:Name="cbVocabulary" Content="{Binding Text}" Checked="CheckBox_Checked" Unchecked="UncheckBox" />
<!--</StackPanel>-->
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</controls:PivotItem>
The list is virtual - controls are created as they are needed and potentially reused (I think).
Your options are to turn the ListBox to not be virtualized (override the template, and for the container, instead of a SerializedStackPanel, choose a regular StackPanel).
Your other (and preferable) option is to do the checking via Data Binding. Way easier and faster in most situations.
I filled the icBoard with 50 Cell objects, so each Rectangle object has Cell as data object. Now, I want according to index or cell object to get the corresponding Rectangle element. For example I want to get the Rectangle in index=15. Not it's data but the Rectangle itself.
How I can do this?
public MainPage()
{
InitializeComponent();
var cells = new List<Cell>();
for (int i = 0; i < 50; i++)
{
cells.Add(new Cell());
}
icCells.ItemsSource = cells;
}
public void sector_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
//some code
//....
var tappedRectangle = (sender as Rectangle);
var spesificRectangle = SOMEHOW_GET_RECTANGLE_AT_POSITION_15;
}
<ItemsControl Name="icBoard" Grid.Column="0" Margin="0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Fill="#501e4696" Width="30" Height="30" Margin="1" Tap="sector_Tap" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
I believe this might work:
ContentPresenter contentPresenter = itemsControl.ItemContainerGenerator.ContainerFromIndex(15) as ContentPresenter;
Rectangle rectangle= FindVisualChild<Rectangle>(contentPresenter );
if (rectangle != null)
{
}
public static T FindVisualChild<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
return (T)child;
}
T childItem = FindVisualChild<T>(child);
if (childItem != null) return childItem;
}
}
return null;
}
It's very simple task, but I struggle for hours.
I have parse xml from web sources and bind them to listbox. Now I want to make an index for each items binded to list box, something like this:
1.Title 2.Title 3.Title
Author Author Author
Date Date Date
Here is what I have so far:
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Name="stkPnl" Orientation="Horizontal" Margin="15,0" MouseEnter="stkPnl_MouseEnter" MouseLeave="stkPnl_MouseLeave">
<Image x:Name="imageAV" Source="{Binding avlink}" Height="80" Width="80"
Stretch="UniformToFill" MouseLeftButtonUp="imageAV_MouseLeftButtonUp" ImageFailed="imageAV_ImageFailed"/>
<StackPanel Orientation="Vertical" Margin="10,0,0,0" MouseLeftButtonUp="StackPanel_MouseLeftButtonUp">
<TextBlock Text="{Binding nickname}" Width="Auto" />
<TextBlock Text="{Binding track}" FontWeight="Bold" Width="Auto"/>
<TextBlock Text="{Binding artist}" Width="Auto"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
and MainPage.xaml.cs
private void DoWebClient()
{
var webClient = new WebClient();
webClient.OpenReadAsync(new Uri("http://music.mobion.vn/api/v1/music/userstop?devid="));
webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);
}
void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
using (var reader = new StreamReader(e.Result))
{
string s = reader.ReadToEnd();
Stream str = e.Result;
str.Position = 0;
XDocument xdoc = XDocument.Load(str);
var data = from query in xdoc.Descendants("user")
select new mobion
{
avlink = (string)query.Element("user_info").Element("avlink"),
nickname = (string)query.Element("user_info").Element("nickname"),
track = (string)query.Element("track"),
artist = (string)query.Element("artist"),
};
listBox.ItemsSource = data;
}
}
As you see I only have nickname, track and artist, if I want to add an index that increase for each listboxItem, how can I do that?
Thank you for reading this question.
I know it's ugly, but it's an idea: Create a wrapper class for around your mobion class:
public class mobionWrapper : mobion
{
public int Index { get; set; }
}
Instead of selecting mobion instances you select mobionWrapper instances:
var data = from query in xdoc.Descendants("user")
select new mobionWrapper
{
avlink = (string)query.Element("user_info").Element("avlink"),
nickname = (string)query.Element("user_info").Element("nickname"),
track = (string)query.Element("track"),
artist = (string)query.Element("artist"),
};
After binding the your data, set the Index property of your wrapper class:
listBox.ItemsSource = data;
for(int i = 0; i < listBox.Items.Count; i++)
{
var item = listBox.Items[i] as mobionWrapper;
item.Index = i + 1;
}
Now you need a new TextBlock and bind it to the Index property:
<TextBlock Text="{Binding Index}" Width="Auto" />
Worked for me. Keep in mind that the index might be invalid after sorting or filtering the data display.
Assuming you've an appropriate field in you mobion class (which you can bind to in the view), you can use an incrementing counter to populate this field as the document is iterated over.
int[] counter = { 1 };
var data = from query in xdoc.Descendants("user")
select new mobion
{
index = counter[0]++,
avlink = (string)query.Element("user_info").Element("avlink"),
nickname = (string)query.Element("user_info").Element("nickname"),
track = (string)query.Element("track"),
artist = (string)query.Element("artist"),
};
Note that counter is an array of int rather than just an int to prevent accessing a modified closure.