如何获得WPF的另一个控件,该控件在c#中具有相同的父控件,而不使用其名称propty?
我在XAML中有以下代码片段如何获得WPF的另一个控件,该控件在c#中具有相同的父控件,而不使用其名称propty?,c#,wpf,xaml,lambda,uicontrol,C#,Wpf,Xaml,Lambda,Uicontrol,我在XAML中有以下代码片段 <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="01*"/> <ColumnDefinition Width="01*"/> </Grid.ColumnDefinitions> <TextBlock Grid.Column="1" Text="ABC" Name="txtBloc
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="01*"/>
<ColumnDefinition Width="01*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1" Text="ABC" Name="txtBlockABC"/>
<TextBlock Grid.Column="2" Text="DEF"/>
</Grid>
但它使用其索引进行访问,而不是使用其文本
属性
我想要类似于Lamba表达式的东西
。比如:
TextBlock txtBlockDEF = (List<TextBlock>) ((Grid) (txtBlock1stPlane.Parent)).Children.All().Where(x => x.Text = "DEF").ToList()[0];
TextBlock txtBlockDEF=(列表)((网格)(txtBlock1stPlane.Parent)).Children.All()。其中(x=>x.Text=“DEF”).ToList()[0];
更新:
其目的是将所选TextBlock
的Text
与其相邻的TextBlock
交换
其目的是将所选文本块的文本与其相邻的文本块交换“
正如我所怀疑的,你肯定是用错误的方式做的
您应该有一个视图模型。该视图模型应该有两个属性,表示两个TextBlock
元素所显示的文本。每个元素都应该将其text
属性绑定到相应的视图模型属性。然后,当您要交换值时,只需交换视图模型上的值(您可以直接访问)
如果没有好的解决方案,就不可能提供关于您自己的代码的任何特定建议。但以下是基本想法:
class MyViewModel : INotifyPropertyChanged
{
private string _text1;
private string _text2;
public string Text1
{
get { return _text1; }
set { _UpdateField(ref _text1, value); }
}
public string Text2
{
get { return _text2; }
set { _UpdateField(ref _text2, value); }
}
public ICommand SwapValues { get; }
public MyViewModel()
{
SwapValues = new SwapValuesCommand(this);
}
private class SwapValuesComand : ICommand
{
private readonly MyViewModel _owner;
public SwapValuesCommand(MyViewModel owner)
{
_owner = owner;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter) { return true; }
public void Execute(object parameter)
{
string temp = _owner.Text1;
_owner.Text1 = _owner.Text2;
_owner.Text2 = temp;
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void _UpdateField<T>(ref T field, T newValue, [CallerMemberName] string propertyName = null)
{
if (!EqualityComparer<T>.Default.Equals(field, newValue))
{
field = newValue;
PropertyChanged?.DynamicInvoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
类MyViewModel:INotifyPropertyChanged
{
私有字符串_text1;
私有字符串_text2;
公共字符串Text1
{
获取{return\u text1;}
设置{u UpdateField(ref _text1,value);}
}
公共字符串Text2
{
获取{return\u text2;}
设置{u UpdateField(ref _text2,value);}
}
公共ICommand交换值{get;}
公共MyViewModel()
{
SwapValues=新的SwapValues命令(此命令);
}
私有类swapvalue命令:ICommand
{
私有只读MyViewModel\u所有者;
公共SwapValuesCommand(MyViewModel所有者)
{
_所有者=所有者;
}
公共事件处理程序CanExecuteChanged;
public bool CanExecute(对象参数){return true;}
public void Execute(对象参数)
{
字符串温度=_owner.Text1;
_owner.Text1=_owner.Text2;
_owner.Text2=温度;
}
}
公共事件属性更改事件处理程序属性更改;
private void\u UpdateField(ref T field,T newValue,[CallerMemberName]string propertyName=null)
{
如果(!EqualityComparer.Default.Equals(字段,newValue))
{
字段=新值;
PropertyChanged?.DynamicInvoke(这是新的PropertyChangedEventArgs(propertyName));
}
}
}
然后在XAML中,类似于:
<Button Content="Swap Values" Command="{Binding SwapValues}"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="01*"/>
<ColumnDefinition Width="01*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1" Text="{Binding Text1}" Name="txtBlockABC"/>
<TextBlock Grid.Column="2" Text="{Binding Text2}"/>
</Grid>
其中,上述所有XAML的DataContext
是MyViewModel
类的一个实例
单击标记为“交换值”的按钮将执行SwapValuesCommand.execute()
方法,该方法将交换值。UI元素的属性将自动更新
我在这里展示了如何使用ICommand
来执行交换,当然,您可以将其连接到您想要的任何逻辑
警告:以上内容都是直接输入到web浏览器中的。我甚至还没有编译,更不用说测试或检查拼写错误等。这只是为了说明。我相信您可以使用它和其他WPF/MVVM示例来理解这里使用的基本设计概念,并调整程序的设计,以便按它应该的方式工作
当然,如果所有其他方法都失败了,我想你可以继续给
TextBlock
一个名称。然后你可以直接访问它。这是一种不明智的方法,但肯定比尝试浏览视觉树、寻找TextBlock
并希望找到正确的方法要好
private void Button_Click(object sender, RoutedEventArgs e)
{
TextBlock t = ((Grid)LogicalTreeHelper.GetParent(txtBlockABC))
.Children.OfType<TextBlock>()
.FirstOrDefault((tb) => { return tb.Text == "DEF"; });
string dummy = txtBlockABC.Text;
txtBlockABC.Text = t.Text;
t.Text = dummy;
}
其目的是将所选文本块的文本与其相邻的文本块交换“
正如我所怀疑的,你肯定是用错误的方式做的
您应该有一个视图模型。该视图模型应该有两个属性,表示两个TextBlock
元素所显示的文本。每个元素都应该将其text
属性绑定到相应的视图模型属性。然后,当您要交换值时,只需交换视图模型上的值(您可以直接访问)
如果没有好的解决方案,就不可能提供关于您自己的代码的任何特定建议。但以下是基本想法:
class MyViewModel : INotifyPropertyChanged
{
private string _text1;
private string _text2;
public string Text1
{
get { return _text1; }
set { _UpdateField(ref _text1, value); }
}
public string Text2
{
get { return _text2; }
set { _UpdateField(ref _text2, value); }
}
public ICommand SwapValues { get; }
public MyViewModel()
{
SwapValues = new SwapValuesCommand(this);
}
private class SwapValuesComand : ICommand
{
private readonly MyViewModel _owner;
public SwapValuesCommand(MyViewModel owner)
{
_owner = owner;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter) { return true; }
public void Execute(object parameter)
{
string temp = _owner.Text1;
_owner.Text1 = _owner.Text2;
_owner.Text2 = temp;
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void _UpdateField<T>(ref T field, T newValue, [CallerMemberName] string propertyName = null)
{
if (!EqualityComparer<T>.Default.Equals(field, newValue))
{
field = newValue;
PropertyChanged?.DynamicInvoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
类MyViewModel:INotifyPropertyChanged
{
私有字符串_text1;
私有字符串_text2;
公共字符串Text1
{
获取{return\u text1;}
设置{u UpdateField(ref _text1,value);}
}
公共字符串Text2
{
获取{return\u text2;}
设置{u UpdateField(ref _text2,value);}
}
公共ICommand交换值{get;}
公共MyViewModel()
{
SwapValues=新的SwapValues命令(此命令);
}
私有类swapvalue命令:ICommand
{
私有只读MyViewModel\u所有者;
公共SwapValuesCommand(MyViewModel所有者)
{
_所有者=所有者;
}
公共事件处理程序CanExecuteChanged;
public bool CanExecute(对象参数){return true;}
public void Execute(对象参数)
{
字符串温度=_owner.Text1;
_owner.Text1=_owner.Text2;
_owner.Text2=温度;
}
}
公共事件属性更改事件处理程序属性更改;
private void\u UpdateField(ref T field,T newValue,[CallerMemberName]string propertyName=null)
{
如果(!EqualityComparer.Default.Equals(字段,newValue))
{
字段=新值;
PropertyChanged?.DynamicInvoke(这是新的PropertyChangedEventArgs(propertyName));
}
}
}
然后在XAML中,类似于:
<Button Content="Swap Values" Command="{Binding SwapValues}"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="01*"/>
<ColumnDefinition Width="01*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1" Text="{Binding Text1}" Name="txtBlockABC"/>
<TextBlock Grid.Column="2" Text="{Binding Text2}"/>
</Grid>