Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何获得WPF的另一个控件,该控件在c#中具有相同的父控件,而不使用其名称propty?_C#_Wpf_Xaml_Lambda_Uicontrol - Fatal编程技术网

如何获得WPF的另一个控件,该控件在c#中具有相同的父控件,而不使用其名称propty?

如何获得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

我在XAML中有以下代码片段

<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>