2016-09-25 27 views
1

我在XAML中有以下代碼片段。如何獲得WPF中具有相同的父母在C#中的其他控件沒有其名稱特權?

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

而且我想通過其他TextBlock名稱(即txtBlockABC)與Text = "DEF"訪問TextBlock在C#。

我嘗試了以下。

TextBlock txtBlockDEF = (TextBlock) ((Grid) (txtBlock1stPlane.Parent)).Children[1]; 

但它訪問它的索引,而不是它的Text屬性。

我想要的東西像Lamba Expression。像:

TextBlock txtBlockDEF = (List<TextBlock>) ((Grid) (txtBlock1stPlane.Parent)).Children.All().Where(x => x.Text = "DEF").ToList()[0]; 

更新:

這樣做的目的是交換選擇TextBlockText與其相鄰TextBlock

+0

_「我想通過其他TextBlock(即txtBlockABC)的名稱在C#中使用Text =」DEF「訪問TextBlock。」_ - 爲什麼?你打算怎麼處理它?你的問題中有很少的細節,它沒有一個很好的[mcve]清楚地說明你的情況。但是,您的問題留下了一個強烈的印象,即您的基本設計存在缺陷。您應該主要通過綁定視圖模型中的屬性和/或通過使用樣式和相關功能來操縱UI元素,如「TextBlock」。 –

+0

如果您提供了一個很好的代碼示例並解釋了您的更廣泛的目標是什麼,那麼您將有更好的機會獲得與設計良好的程序實際一致的良好有用答案。 –

回答

2

這樣做的目的是交換選擇TextBlock的文本與它相鄰的TextBlock」

正如我懷疑,你絕對是做了錯誤的方式。

你應該有一個視圖模型,該視圖模型應該有兩個屬性來表示你的兩個TextBlock元素顯示的文本,每個元素都應該將它們的Text屬性綁定到相應的視圖模型屬性,然後當你想交換這些值時,只需交換視圖模型(您可以直接訪問)的值。

沒有好的Minimal, Complete, and Verifiable code example不可能提供任何關於您自己的代碼的具體建議。但這裏的基本思想是:

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)); 
     } 
    } 
} 

然後在你的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> 

DataContext上述所有XAML的是MyViewModel類的一個實例。

單擊標記爲的按鈕「交換值」將執行SwapValuesCommand.Execute()方法,該方法將交換這些值。 UI元素的屬性將自動更新。

我在這裏展示了使用ICommand來執行交換,但是當然你可以將它鉤住你想要的任何邏輯。

注意事項:上述內容全部輸入到網頁瀏覽器中。我甚至沒有編譯它,沒有介意測試它或檢查它是否有錯別字等。這僅僅是爲了說明的目的。我相信您可以使用它和其他WPF/MVVM示例來了解這裏使用的基本設計概念,並調整程序的設計,使其按照預期的方式工作。


當然,如果一切都失敗了,我想你可以繼續給TextBlock一個名字。然後你可以直接訪問它。這是一個不明智的做法,但它肯定是比試圖瀏覽視覺樹更好的選擇,尋找TextBlock並希望你找到合適的。

-2
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; 
} 
相關問題