I have this flipview:
<FlipView x:Name="models_list" SelectionChanged="selectionChanged"> <FlipView.ItemTemplate> <DataTemplate> <Grid x:Name="cv"> <Image x:Name="img1" Source = "{Binding ModelImage}" Stretch="Fill" Tag="{Binding ModelTag}"/> </Grid> </DataTemplate> </FlipView.ItemTemplate>
I want to find img1 of currently selected index. While searching for it I found this method on some post here:
private DependencyObject FindChildControl<T>(DependencyObject control, string ctrlName) { int childNumber = VisualTreeHelper.GetChildrenCount(control); for (int i = 0; i < childNumber; i++) { DependencyObject child = VisualTreeHelper.GetChild(control, i); FrameworkElement fe = child as FrameworkElement; // Not a framework element or is null if (fe == null) return null; if (child is T && fe.Name== ctrlName) { // Found the control so return return child; } else { // Not found it - search children DependencyObject nextLevel = FindChildControl<T>(child, ctrlName); if (nextLevel != null) return nextLevel; } } return null; }
It returns me the Image on the first index of flipview but I need the one present on the currently selected index.. I tried to edit this method but I am unable to find the required control. Can anyone help me?
Access of the controls from within the same assembly is hence allowed. If you want to access a control on a wpf form from another assembly you have to use the modifier attribute x:FieldModifier="public" or use the method proposed by Jean.
ListBoxItemPhaseListBoxObj = (ListBoxItem)(PhaseListBox… ContainerFromIndex(0)); ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(PhaseListBoxObj);
FindName method of FrameworkElement class is used to find elements or controls by their Name properties.
Data template is a bit of XAML that describes how bound data is displayed. A data template can contain elements that are each bound to a data property along with additional markup that describes layout, color and other appearance.
The problem you are experiencing is that the DataTemplate
is repeating and the content is being generated by the FlipView
. The Name
is not exposed because it would conflict with the previous sibling that was generated (or the next one that will be).
So, to get a named element in the DataTemplate
you have to first get the generated item, and then search inside that generated item for the element you want. Remember, the Logical Tree in XAML is how you access things by name. Generated items are not in the Logical Tree. Instead, they are in the Visual Tree (all controls are in the Visual Tree). That means it is in the Visual Tree you must search for the control you want to reference. The VisualTreeHelper
lets you do this.
Now, how to do it?
I wrote an article on this because it is such a recurring question: http://blog.jerrynixon.com/2012/09/how-to-access-named-control-inside-xaml.html but the meat of the solution is a recursive method that looks something like this:
public void TestFirstName() { foreach (var item in MyFlipView.Items) { var _Container = MyFlipView.ItemContainerGenerator .ContainerFromItem(item); var _Children = AllChildren(_Container); var _FirstName = _Children // only interested in TextBoxes .OfType<TextBox>() // only interested in FirstName .First(x => x.Name.Equals("FirstName")); // test & set color _FirstName.Background = (string.IsNullOrWhiteSpace(_FirstName.Text)) ? new SolidColorBrush(Colors.Red) : new SolidColorBrush(Colors.White); } } public List<Control> AllChildren(DependencyObject parent) { var _List = new List<Control>(); for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) { var _Child = VisualTreeHelper.GetChild(parent, i); if (_Child is Control) _List.Add(_Child as Control); _List.AddRange(AllChildren(_Child)); } return _List; }
The key issue here is that a method like this gets all the children, and then in the resulting list of child controls you can search for the specific control you want. Make sense?
And now to answer your question!
Because you specifically want the currently selected item, you can simply update the code like this:
if (MyFlipView.SelectedItem == null) return; var _Container = MyFlipView.ItemContainerGenerator .ContainerFromItem(MyFlipView.SelectedItem); // then the same as above...
maybe a little more generic approach might be something like this:
private List<Control> AllChildren(DependencyObject parent) { var _List = new List<Control>(); for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) { var _Child = VisualTreeHelper.GetChild(parent, i); if (_Child is Control) { _List.Add(_Child as Control); } _List.AddRange(AllChildren(_Child)); } return _List; } private T FindControl<T> (DependencyObject parentContainer, string controlName) { var childControls = AllChildren(parentContainer); var control = childControls.OfType<Control>().Where(x => x.Name.Equals(controlName)).Cast<T>().First(); return control; }
You would invoke FindControl like this:
var parentContainer = this.flipView.ItemContainerGenerator.ContainerFromItem(this.flipView.SelectedItem); var myImage = FindControl<Image>(parentContainer, "img1"); //suppose you want to change the visibility myImage.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With