如何在特定的ListBox索引中按名称访问元素 [英] How to access element by name at a specific ListBox index
问题描述
我有一个上面有几个项目的ListBox(TextBlocks,Images等),我想做的是通过特定ListBox索引处的名称访问元素.
I have a ListBox with several items on it (TextBlocks, Images and so on), what I'm trying to do is access an element by it's name at a specific ListBox index.
我知道需要访问的元素名称和索引,在这种情况下,我需要将图像控件的可见性属性更改为折叠.
I know the element name and the index i need to access, in this case I need to change the visibility property of an image control to collapsed.
I've looked at a few examples using VisualTreeHelper
here but they were only to access element by name, not by name and index, which is what i need to do but have not been able to.
谢谢,鲍勃.
推荐答案
我实现了一个小演示,以强调使用MVVM模式的数据绑定.
在此示例中,通过取消/选中Checkbox
,使用绑定到TextBlock.Visibility
的ShowTextbox属性切换TextBlock
可见性.
I implemented a small demo to emphasize data binding using MVVM patern.
In this example I toggle the TextBlock
visibility using ShowTextbox property bound to the TextBlock.Visibility
by un/checking the Checkbox
.
App.xaml.cs
App.xaml.cs
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var mainViewModel = new MainViewModel
{
ListItems = new ObservableCollection<MyModel>
{
new MyModel
{
MyPropertyText = "hello",
ShowText = true,
ShowTextbox = Visibility.Visible
}
}
};
var app = new MainWindow() {DataContext = mainViewModel};
app.Show();
}
}
MainWindow.xaml
MainWindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication1="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ListBox HorizontalAlignment="Left" Height="148" VerticalAlignment="Top" Width="299" Margin="30,57,0,0" ItemsSource="{Binding Path=ListItems}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path=MyPropertyText}" Visibility="{Binding Path=ShowTextbox}"/>
<CheckBox IsChecked="{Binding ShowText}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
MainWindow.cs
MainWindow.cs
public partial class MainWindow : Window
{
private MainViewModel _mainViewModel;
public MainWindow()
{
InitializeComponent();
}
}
MainViewModel.cs
MainViewModel.cs
public class MainViewModel : ObservableObject
{
public ObservableCollection<MyModel> ListItems
{
get { return _listItems; }
set
{
_listItems = value;
RaisePropertyChanged("ListItems");
}
}
}
MyModel.cs
MyModel.cs
public class MyModel : ObservableObject
{
private string _myPropertyText;
private bool _showText;
private Visibility _showTextbox;
public string MyPropertyText
{
get { return _myPropertyText; }
set
{
_myPropertyText = value;
RaisePropertyChanged("MyPropertyText");
}
}
public bool ShowText
{
get { return _showText; }
set
{
_showText = value;
RaisePropertyChanged("ShowText");
ShowTextbox = value ? Visibility.Visible : Visibility.Collapsed;
}
}
public Visibility ShowTextbox
{
get { return _showTextbox; }
set
{
_showTextbox = value;
RaisePropertyChanged("ShowTextbox");
}
}
}
ObservableObject.cs
ObservableObject.cs
public class ObservableObject : INotifyPropertyChanged
{
#region Constructor
public ObservableObject() { }
#endregion // Constructor
#region RaisePropertyChanged
/// <summary>
/// Raises this object's PropertyChanged event.
/// </summary>
/// <param name="propertyName">The property that has a new value.</param>
protected virtual void RaisePropertyChanged(string propertyName = "")
{
VerifyPropertyName(propertyName);
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
#endregion
#region Debugging Aides
/// <summary>
/// Warns the developer if this object does not have
/// a public property with the specified name. This
/// method does not exist in a Release build.
/// </summary>
[Conditional("DEBUG")]
[DebuggerStepThrough]
public void VerifyPropertyName(string propertyName)
{
// If you raise PropertyChanged and do not specify a property name,
// all properties on the object are considered to be changed by the binding system.
if (String.IsNullOrEmpty(propertyName))
return;
// Verify that the property name matches a real,
// public, instance property on this object.
if (TypeDescriptor.GetProperties(this)[propertyName] == null)
{
string msg = "Invalid property name: " + propertyName;
if (this.ThrowOnInvalidPropertyName)
throw new ArgumentException(msg);
else
Debug.Fail(msg);
}
}
/// <summary>
/// Returns whether an exception is thrown, or if a Debug.Fail() is used
/// when an invalid property name is passed to the VerifyPropertyName method.
/// The default value is false, but subclasses used by unit tests might
/// override this property's getter to return true.
/// </summary>
protected virtual bool ThrowOnInvalidPropertyName { get; private set; }
#endregion // Debugging Aides
#region INotifyPropertyChanged Members
/// <summary>
/// Raised when a property on this object has a new value.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
#endregion // INotifyPropertyChanged Members
}
这篇关于如何在特定的ListBox索引中按名称访问元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!