I want to change the Foreground of a item on a ListView of my UWP.
I am using:
int i_DeleteRow = ListView1.SelectedIndex;
var item = ListView1.Items[i_DeleteRow] as ListViewItem;
if (item != null)
{
item.Foreground = new SolidColorBrush(Colors.Red);
}
But with this code item is always null.
Any help is appreciated.
You need to use ItemContainerGenerator.ContainerFromIndex. It returns a DependencyObject then you can cast it to ListBoxItem and use the ListBoxItem's properties like Foreground:
ListViewItem item = (ListViewItem)(ListView1.ItemContainerGenerator.ContainerFromIndex(ListView1.SelectedIndex));
if (item != null)
{
item.Foreground = new SolidColorBrush(Colors.Red);
}
Related
I want to sort a list that contains custom control.
The list has a list of listboxitem that have content with a checkbox inside, and the checkbox has a textblock inside.
List<ListBoxItem> listboxItem =new List<ListBoxItem>();
Some code that add the control into listboxItem with for loop
{
ListBoxItem lbi = new ListBoxItem();
CheckBox chkBox = new CheckBox();
TextBlock txtBlock = new TextBlock();
txtBlock.Text = sometext;
chkBox.Content = txtBlock;
lbi.Content = chkBox;
listBoxItems.Add(lbi);
}
listboxItems.Sort();
And I have implement IComparable interface
public int CompareTo(Object obj)
{
if (obj == null) return 1;
List<ListBoxItem> listBoxItems = obj as List<ListBoxItem>;
for (int i = 0; i < listBoxItems.Count; i++)
{
if (i < listBoxItems.Count)
{
ListBoxItem listBoxItem = listBoxItems[i];
ListBoxItem lbi = this.listBoxItems[i];
CheckBox checkBox = listBoxItem.Content as CheckBox;
CheckBox chk = lbi.Content as CheckBox;
TextBlock textBlock = checkBox.Content as TextBlock;
TextBlock txt = chk.Content as TextBlock;
return string.Compare(txt.Text, textBlock.Text);
}
}
return 0;
}
And it still give me error that need to implement Icomparable.
Not sure is it implement or use correctly, pretty new to me for this implementation #.#
Just found out that can use Linq and Tag to get rid of IComparable.
Edited Code:
Some code that add the control into listboxItem with for loop
{
ListBoxItem lbi = new ListBoxItem();
CheckBox chkBox = new CheckBox();
TextBlock txtBlock = new TextBlock();
txtBlock.Text = sometext;
chkBox.Content = txtBlock;
lbi.Content = chkBox;
lbi.Tag = sometext;
listBoxItems.Add(lbi);
}
listBoxItems = listBoxItems.OrderBy(x => x.Tag).ToList();
Then, the list will be sort in alphabetic perfectly.
I use this code to add a TextBox to a DataGrid cell: (no, I can't use XAML here)
Binding binding = new Binding("Fld_Company");
binding.Mode = BindingMode.OneWay;
FrameworkElementFactory frameworkElementFactory = new FrameworkElementFactory(typeof(TextBox));
DataTemplate dataTemplate = new DataTemplate();
dataTemplate.VisualTree = frameworkElementFactory;
frameworkElementFactory.SetBinding(TextBox.TextProperty, binding);
DataGridTemplateColumn dataGridTemplateColumn = new DataGridTemplateColumn();
dataGridTemplateColumn.IsReadOnly = true;
dataGridTemplateColumn.Header = "Company";
dataGridTemplateColumn.CellTemplate = dataTemplate;
this.dataGrid.Columns.Add(dataGridTemplateColumn);
I there a way to get the underlying TextBox control without XAML?
What I tried:
VisualTreeHelper, but the GetChildrenCount() is always 0
FindName, but I haven't found a proper FrameworkElement
After explored the DataGrid for a while I see that my question does not make any sense. My code above prepares just the DataGrid but does not fill any data. Until that no rows are generated and therefore no underlying TextBox controls can be found.
When the DataGrid gets finally filled with data, the best way to get the underlying controls seems to be catching the LoadinRow event. But when this event fires, the loading of the row is not finished. There needs to be temporarily assigned a second event which fires when the row is finally loaded.
{
DataGrid.LoadingRow += DataGrid_LoadingRow;
}
private void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
// The visual tree is not built until the row is "loaded". This event fires when this happend:
e.Row.Loaded += DataGrid_Row_Loaded;
}
private void DataGrid_Row_Loaded(object sender, RoutedEventArgs e)
{
DataGridRow dataGridRow = (DataGridRow)sender;
// important: Remove the event again
dataGridRow.Loaded -= DataGrid_Row_Loaded;
NestedGridFieldProperty ngrProp = (NestedGridFieldProperty)dataGridRow.Item;
// Get the "presenter", which contains the cells
DataGridCellsPresenter presenter = coNeboTools.ConeboMisc.GetVisualChild<DataGridCellsPresenter>(dataGridRow);
// Get the cells in the presenter
var cells = GetVisualChildren<DataGridCell>(presenter);
// Get the underlying TextBox in column 0
TextBox underlyingTextBox = (TextBox)cells.ElementAt(0).Content;
// the Item property of the row contains the row data
var myData = dataGridRow.Item;
// do what ever is needed with the TextBlock
underlyingTextBox.Foreground = Brushes.Red;
}
// Static helper method to handle the visual tree
public static IEnumerable<T> GetVisualChildren<T>(DependencyObject dependencyObject)
where T : DependencyObject
{
if (dependencyObject != null)
{
int childrenCount = VisualTreeHelper.GetChildrenCount(dependencyObject);
for (int i = 0; i < childrenCount; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(dependencyObject, i);
if (child != null && child is T)
{
yield return (T)child;
}
foreach (T childOfChild in GetVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}
// Static helper method to handle the visual tree
public static childItem GetVisualChild<childItem>(DependencyObject obj)
where childItem : DependencyObject
{
foreach (childItem child in GetVisualChildren<childItem>(obj))
{
return child;
}
return null;
}
I need to find a ScrollViewer inside current TabItem and then find a WrapPanel inside that ScrollViewer
I tried this:
TabItem ti = tabControl.SelectedItem as TabItem;
foreach (ScrollViewer sv in ti.Content)
{
foreach (WrapPanel wp in sv.Content) {}
}
and this
TabItem ti = tabControl.SelectedItem as TabItem;
foreach (ScrollViewer sv in ti.Children)
{
foreach (WrapPanel wp in sv.Children) {}
}
But doesn't work
If your tab item contains your scrollviewer directly, you could do the following :
TabItem ti = tabControl.SelectedItem as TabItem;
ScrollViewer sv = ti?.Content as ScrollViewer;
WrapPanel wp = scrollViewer?.Content as WrapPanel;
Another way of accessing your WrapPanel would be to use a function that returns a child/content of a specific type. For instance
public T FindVisualChildOrContentByType<T>(DependencyObject parent)
where T : DependencyObject
{
if(parent == null)
{
return null;
}
if(parent.GetType() == typeof(T))
{
return parent as T;
}
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
if(child.GetType() == typeof(T))
{
return child as T;
}
else
{
T result = FindVisualChildOrContentByType<T>(child);
if (result != null)
return result;
}
}
if(parent is ContentControl contentControl)
{
return this.FindVisualChildOrContentByType<T>(contentControl.Content as DependencyObject);
}
return null;
}
Then you would be able to do
WrapPanel wp = this.FindVisualChildOrContentByType<WrapPanel>(tabItem);
If this is not working, feel free to post your XAML so i can reproduce your exact scenario.
How can i access a Textblock inside a Stackpanel that is inside a ListBoxItem?
For example:
ListBoxItem MyItem = new ListBoxItem();
StackPanel StackPnl = new StackPanel();
TextBlock Title = new TextBlock();
Title.Text = "Item 1";
StackPnl.Children.Add(Title);
MyItem.Content = StackPnl;
How can i later access the Text property of that Textblock with Listbox.SelectedItem?
Try this:
//listBox1 is your ListBox
ListBoxItem MyItem = listBox1.SelectedItem as ListBoxItem;
if(MyItem != null)
{
StackPanel sp = MyItem.Content as StackPanel;
if(sp != null && sp.Children.Count > 0)
{
TextBlock textBlock = sp.Children[0] as TextBlock;
if(textBlock != null)
{
string text = textBlock.Text;
}
}
}
I have a series of controls that can be passed around and on occasion they are added as a child to another control.
In many cases I cannot know for certain if the control is currently the child of another control.
For example :
Label lbl = new Label( );
/*Stuff happens; lbl may be assigned or not; whatever.*/
//If the label has already been assigned as a child to a viewbox
if ( lbl.Parent is Viewbox )
return lbl.Parent;
else {
if (lbl.Parent != null )
//Of course this fails because there is no lbl.Parent.Child property.
lbl.Parent.Child = null;
return new Viewbox( ) { Child = lbl, Stretch = Stretch.Uniform };
}
It is entirely possible I am completely misinterpreting the function of the Control.Parent property.
Is it possible to orphan a control from it's parent through the control itself?
void RemoveElementFromItsParent(FrameworkElement el)
{
if (el.Parent == null)
return;
var panel = el.Parent as Panel;
if (panel != null)
{
panel.Children.Remove(el);
return;
}
var decorator = el.Parent as Decorator;
if (decorator != null)
{
decorator.Child = null;
return;
}
var contentPresenter = el.Parent as ContentPresenter;
if (contentPresenter != null)
{
contentPresenter.Content = null;
return;
}
var contentControl = el.Parent as ContentControl;
if (contentControl != null)
contentControl.Content = null;
}
source: https://stackoverflow.com/a/19318405/1271037