WP7 find control inside header of pivotitem - windows-phone-7

For my WP7 app, I need to find a date control which I have placed in the header template of the pivotitem.
How do I access this datepicker control in the code behind for the currently selected PivotItem?
public static T FindName<T>(string name, DependencyObject reference) where T : FrameworkElement
{
if (string.IsNullOrEmpty(name))
{
throw new ArgumentNullException("name");
}
if (reference == null)
{
throw new ArgumentNullException("reference");
}
return FindNameInternal<T>(name, reference);
}
private static T FindNameInternal<T>(string name, DependencyObject reference) where T : FrameworkElement
{
foreach (DependencyObject obj in GetChildren(reference))
{
T elem = obj as T;
if (elem != null && elem.Name == name)
{
return elem;
}
elem = FindNameInternal<T>(name, obj);
if (elem != null)
{
return elem;
}
else
{
//if (obj.GetType().FullName == "System.Windows.Controls.DataField")
// elem = (obj as DataField).Content as T;
if (elem != null && elem.Name == name)
return elem;
}
}
return null;
}
private static IEnumerable<DependencyObject> GetChildren(DependencyObject reference)
{
int childCount = VisualTreeHelper.GetChildrenCount(reference);
if (childCount > 0)
{
for (int i = 0; i < childCount; i++)
{
yield return VisualTreeHelper.GetChild(reference, i);
}
}
}

I don't know of any real good solution to this. I guess my initial thought was why do you need a reference to the DatePicker object? But I guess you have your reasons.
A possible solution though:
You could use the VisualTreeHelper to traverse the visual tree from your pivot item and stop when you find an object of the correct type (DatePicker). Create a helper function like this:
private static DependencyObject GetDependencyObjectFromVisualTree(DependencyObject startObject, Type type)
{
DependencyObject parent = startObject;
while (parent != null)
{
if (type.IsInstanceOfType(parent))
break;
parent = VisualTreeHelper.GetParent(parent);
}
return parent;
}
Then call it with the PivotItem as the DependencyObject, typeof(DatePicker) as the type and finally cast the returned DependencyObject to a DatePicker.
HTH

The regular Parent/Child relationship doesn't really work for the Pivot control. What you can do is search for the DatePicked component directly in the PivotItem:
((DatePicker)((PivotItem)MainPivot.SelectedItem).FindName("DateControl"))
MainPivot is the Pivot control. I am getting the currently selected item via SelectedItem - notice that I am casting it to PivotItem directly, since otherwise I get an object. Then I am looking for a control named DateControl, given that you have a x:Name set for it.
All that needs to be done after that is cast the object to DatePicker and access its properties the same way you would do for any other control.

Related

How can we get the children(calendardayitem) of parent object(calendarview) in winui?

In UWP,we can fetch the children by FindDescendants<> .But in winui, we can't able to do that.
By doing with visualhelpertree,It always shows zero count in getchildCount() from the calendarview
I just wanted to know how to fetch the children of calendarview .
Also i have tried this but shows me zero child always,
private void FindDescendants1(DependencyObject parent, Type targetType)
{
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
itemchange.Text = childrenCount.ToString();
for (int i = 0; i < childrenCount; i++)
{
var child =(CalendarViewDayItem) VisualTreeHelper.GetChild(parent, i);
if (child.GetType() == targetType)
{
results.Add(child);
}
FindDescendants1(child, targetType);
}
}
Simply I have created this function to get the child and called,
foreach (DependencyObject displayedDay in results)
{
//displayedDay = (CalendarViewDayItem)displayedDay;
CalendarViewDayItem c = displayedDay as CalendarViewDayItem;
if (_highlightedDates.Contains(c.Date))
{
Console.WriteLine(c.Date.ToString());
//highlight
c.Background = new SolidColorBrush(Colors.Red);
}
itemchange.Text = c.Date.ToString();
}
But this not getting the child ,results is the list of objects here where it always show me zero .
My first guess is that you are calling FindDescendants1() before the control is loaded, in the constructor for example. If your CalendarView is in a Page, try calling FindDescendants1() in the Page's Loaded event.
But there's another problem in you code below.
var child = (CalendarViewDayItem)VisualTreeHelper.GetChild(parent, i);
You'll get an exception because you're trying to cast every DependencyObject to a CalendarViewDayItem. By removing the cast you should get the CalendarViewItems. Though, I would make the FinDescendants() static and just receive the results:
private static IEnumerable<T> FindDescendantsOfType<T>(DependencyObject parent) where T : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(parent, i);
if (child is T hit)
{
yield return hit;
}
foreach (T? grandChild in FindChildrenOfType<T>(child))
{
yield return grandChild;
}
}
}
And use it like this:
this.results = FindChildrenOfType<CalendarViewDayItem>(this.CalendarViewControl);
foreach (var item in this.results)
{
// Do you work here...
}

Windows Form Multi-Select for Tree View

Is there a way to multi-select in a Windows Tree View? Similar to the image below
I know that .NET currently doesn't have a multiselect treeview. It is treated as a wrapper around the win32 native treeview control. I would like to avoid the Treeview's Checkbox property if possible. Any suggestions is greatly appreciated!
Im gonna assume you're trying to avoid check boxes. Here is an example:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
treeView1.DrawMode = OwnerDrawText;
treeView1.DrawNode += treeView1_DrawNode;
treeView1.NodeMouseClick += treeView1_NodeMouseClick;
}
private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e) {
// Show checked nodes with an underline
using (SolidBrush br = new SolidBrush(e.Node.TreeView.BackColor))
e.Graphics.FillRectangle(br, e.Node.Bounds);
Font nodeFont = e.Node.NodeFont;
if (nodeFont == null) nodeFont = e.Node.TreeView.Font;
if (e.Node.Checked) nodeFont = new Font(nodeFont, FontStyle.Underline);
using (SolidBrush br = new SolidBrush(e.Node.TreeView.ForeColor))
e.Graphics.DrawString(e.Node.Text, nodeFont, br, e.Bounds);
if (e.Node.Checked) nodeFont.Dispose();
}
private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) {
if (Control.ModifierKeys == Keys.Shift && e.Node.Parent != null) {
// Extend selection
bool check = false;
foreach (TreeNode node in e.Node.Parent.Nodes) {
if (node.Checked) check = true;
node.Checked = check;
if (node == e.Node) break;
}
}
else {
unselectNodes(treeView1.Nodes);
e.Node.Checked = true;
}
}
This question has been answered here but I'll briefly answer your question. While it is true that Native Treeview control does not allow multiple selection, you can derive a subclass from it and override its behaviors.
Example code:
checkNodes method:
private void checkNodes(TreeNode node, bool check)
{
foreach (TreeNode child in node.Nodes)
{
if (child.Checked == true)
{
MessageBox.Show(child.Text);
}
//MessageBox.Show(child.Text);
checkNodes(child, check);
}
}
Treeview method after check:
private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
if (e.Action != TreeViewAction.Unknown)
{
if (busy) return;
busy = true;
try
{
TreeNode _node = e.Node;
checkNodes(e.Node, e.Node.Checked);
if (e.Node.Checked)
{
MessageBox.Show(e.Node.Text);
}
}
finally
{
busy = false;
}
}
}
It is not trivial to do so, however it can be done.

C# Sort array of Objects by object type (Icomparable?)

I want to sort anarray by the object type. So all songs are together, all book are together, and all movies are together.
I am reading a file and determine what each object should be. then creating the object and adding it to the array.
EDIT: Here is the actual code.
static Media[] ReadData()
{
List<Media> things = new List<Media>();
try
{
String filePath = "resources/Data.txt";
string Line;
int counter = 0; // used to check if you have reached the max
number of allowed objects (100)
using (StreamReader File = new System.IO.StreamReader(filePath))
{
while ((Line = File.ReadLine()) != null)
{
This is where each object is created. The file
search for a key word in the beginning of the line, then
creates the corresponding object. It will split the
information on the first line of the object and will
read each line until a "-" character is found and
pass each line into the summary. The summary is then
decrypted and the created object is passed into an
array List. Finally if the array list reaches 100, it
will print "You have reach max number of objects" and
stop reading the file.
if (Line.StartsWith("BOOK"))
{
String[] tempArray = Line.Split('|');
//foreach (string x in tempArray){Console.WriteLine(x);} //This is used
for testing
Book tempBook = new Book(tempArray[1],
int.Parse(tempArray[2]), tempArray[3]);
while ((Line = File.ReadLine()) != null)
{
if (Line.StartsWith("-")){break;}
tempBook.Summary = tempBook.Summary + Line;
}
tempBook.Summary = tempBook.Decrypt();
things.Add(tempBook);
counter++;
}
else if (Line.StartsWith("SONG"))
{
String[] tempArray = Line.Split('|');
//foreach (string x in tempArray)
{Console.WriteLine(x);} //This is used for testing
Song tempSong = new Song(tempArray[1],
int.Parse(tempArray[2]), tempArray[3], tempArray[4]);
things.Add(tempSong);
counter++;
}
else if (Line.StartsWith("MOVIE"))
{
String[] tempArray = Line.Split('|');
//foreach (string x in tempArray)
{Console.WriteLine(x);} //This is used for testing
Movie tempMovie = new Movie(tempArray[1],
int.Parse(tempArray[2]), tempArray[3]);
while ((Line = File.ReadLine()) != null)
{
if (Line.StartsWith("-")) { break; }
tempMovie.Summary = tempMovie.Summary + Line;
}
tempMovie.Summary = tempMovie.Decrypt();
things.Add(tempMovie);
counter++;
}
if (counter == 100)
{
Console.WriteLine("You have reached the maximum number of media
objects.");
break;
}
}
File.Close();
}
}
return things.ToArray(); // Convert array list to an Array and return the
array.
}
In the main code, I have this:
Media[] mediaObjects = new Media[100];
Media[] temp = ReadData();
int input; // holds the input from a user to determin which action to take
for (int i = 0; i<temp.Length;i++){ mediaObjects[i] = temp[i]; }
I want the array of mediaObjects to be sorted by the what type of objects.
I have also used Icomparable to do an arrayList.sort() but still no luck.
public int CompareTo(object obj)
{
if (obj == null)
{
return 1;
}
Song temp = obj as Song;
if (temp != null)
{
//Type is a string
return this.Type.CompareTo(temp.Type);
}
else
{
return 1;
}
}
So I see you have BOOK, SONG and MOVIE types.
This is a classic case of implementing the IComparable interface - although you are correct with the interface name to implement, you are not using this correctly.
Create a base class by the name MediaObject - this will be the main one for your other types of objects you create.
Add the correct properties you need. In this case, the media type is the one in need.
Let this class implement IComparable to help you with the comparison.
override the CompareTo() method in the PROPER way
public class MediaObject : IComparable
{
private string mediaType;
public string MediaType
{
get {return mediaType;}
set {mediaType=value;}
}
public MediaObject(string mType)
{
MediaType = mType;
}
int IComparable.CompareTo(object obj)
{
MediaObject mo = (MediaObject)obj;
return String.Compare(this.MediaType,mo.MediaType); //implement a case insensitive comparison if needed (for your research)
}
}
You can now compare the MediaObject objects In your main method directly.
Thank for the advice. I ended up just reformating how I was creating the list while reading it. I made multiple lists for each object then just happened each one on to the master list so It showed up sorted. I wish I figured that out before I made this long post.
As far as I could find, you can't sort by the type of object in a generic array. If anyone has a better solution feel free to post it.

Is it possible to handle the Visual State Changed event for the Windows Phone Toolkit HubTile?

I would like to change the Source (Image) of a HubTile when the Visual State changes to Flipped however I don't seem to be able to get the VisualStateManager.GetVisualStateGroups working for the HubTile control from the Windows Phone Toolkit.
I presume that once I have the VisualStateGroup I can then handle the CurrentStateChanged event however I don't seem to be able to get the group.
I have seen the following thread which unfortunately doesn't include a code snippet :-
Changing image source when Hubtile "resets"
I have also tried to use the VisualTreeHelper.GetChild, which I don't think is required.
I would be very grateful if you could share some ideas?
Based on the following blog post :-
http://blogs.msdn.com/b/ptorr/archive/2010/07/23/how-to-detect-when-a-list-is-scrolling-or-not.aspx
I came up with the following :-
bool alreadyHookedEvents = false;
List<string> _images = new List<string>();
int _index = 0;
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
if (_images.Count == 0)
{
_images.Add(#"\Images\1.jpg");
_images.Add(#"\Images\2.jpg");
_images.Add(#"\Images\3.jpg");
_images.Add(#"\Images\4.jpg");
_images.Add(#"\Images\5.jpg");
_images.Add(#"\Images\6.jpg");
_images.Add(#"\Images\7.jpg");
_images.Add(#"\Images\8.jpg");
_images.Add(#"\Images\9.jpg");
_images.Add(#"\Images\10.jpg");
_images.Add(#"\Images\11.jpg");
_images.Add(#"\Images\12.jpg");
}
if (alreadyHookedEvents)
return;
alreadyHookedEvents = true;
// Visual States are always on the first child of the control template
FrameworkElement element = VisualTreeHelper.GetChild(this.MyHubTile, 0) as FrameworkElement;
if (element != null)
{
VisualStateGroup group = FindVisualState(element, "ImageStates");
if (group != null)
{
group.CurrentStateChanged += (s, args) =>
{
if (group.CurrentState.Name == "Flipped")
{
_index++;
this.MyHubTile.Source = new BitmapImage(new Uri(_images[_index], UriKind.Relative));
}
};
}
}
}
VisualStateGroup FindVisualState(FrameworkElement element, string name)
{
if (element == null)
return null;
IList groups = VisualStateManager.GetVisualStateGroups(element);
foreach (VisualStateGroup group in groups)
if (group.Name == name)
return group;
return null;
}
T FindSimpleVisualChild<T>(DependencyObject element) where T : class
{
while (element != null)
{
if (element is T)
return element as T;
element = VisualTreeHelper.GetChild(element, 0);
}
return null;
}

Saving a custom object using IsloatedStorageSettings

I'm trying to save an object in IsolatedStorageSettings to save the high scores for my game, but whenever I try to save an updated copy of the object C# seems to think the object hasn't changed. I tried creating a custom Equals function for the HighScores class but that doesn't seem to help.
Any idea what I'm doing wrong?
Thanks
public bool AddOrUpdateValue(string Key, Object value)
{
bool valueChanged = false;
// If the key exists
if (isolatedStore.Contains(Key))
{
// If the value has changed
if (isolatedStore[Key] != value) //This keeps returning false
{
// Store the new value
isolatedStore[Key] = value;
valueChanged = true;
}
}
// Otherwise create the key.
else
{
isolatedStore.Add(Key, value);
valueChanged = true;
}
return valueChanged;
}
//This is located inside the HighScores class
public bool Equals(HighScores newHighScores)
{
for (int i = 0; i < highScores.Length; i++)
{
if (!highScores[i].Name.Equals(newHighScores.GetIndex(i).Name))
{
return false;
}
if (!highScores[i].Time.Equals(newHighScores.GetIndex(i).Time))
{
return false;
}
}
return true;
}
You haven't implemented the equality operators '==' and '!=' and these compare reference equality, you are going to have provide the implementation which maps on to your 'Equals' method
http://msdn.microsoft.com/en-us/library/ms173147%28v=vs.80%29.aspx
You should do isolatedStore.Save() to commit the changes

Resources