1

I edited last question. I have 2 classes

    public class Signal: INotifyPropertyChanged 
{
    public string Name { get; set;}
    public Int32 Value { get; set;}

    private ObservableCollection < RawVal > rawValue1;
    public ObservableCollection < RawVal > rawValue 
    {
        get  { return rawValue1; }
        set 
        {   rawValue1 = value;
            OnPropertyChanged("rawValue");
            if (value != null && value.Count > 0) 
            {
             SelectedRaValue = value.First();
            }
        }
    }

    private RawVal selectedRaValue;
    public RawVal SelectedRaValue 
    {
        get 
        {
            return selectedRaValue;
        }
        set 
        {
            selectedRaValue = value;
            OnPropertyChanged("SelectedRaValue");
            ComboValue = value.name;
            OnPropertyChanged("ComboValue");
        }
    }    
    public string ComboValue 
    {
        get;
        set;
    }    
    #region Implementation of INotifyPropertyChanged    
    public event PropertyChangedEventHandler PropertyChanged;    
    protected virtual void OnPropertyChanged(string propertyName) 
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }    
    #endregion

}

And Here XAML:

 <DataGrid ItemsSource="{Binding}" Name="grdSignal" Grid.Row="1" CanUserAddRows="False" AutoGenerateColumns="False" SelectionChanged="grdSignal_SelectionChanged_1">
 <DataGrid.Columns>
    <DataGridTextColumn Header="Signal Name" Binding="{Binding Name}" Width="150"/>
                                <DataGridTemplateColumn Header="Physical Value" Width="120">
          <DataGridTemplateColumn.CellTemplate>
             <DataTemplate>
                  <ComboBox ItemsSource="{Binding rawValue, Mode=TwoWay}" SelectedItem="{Binding SelectedRaValue,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  DisplayMemberPath="name" Name="cmbVal"  
                       IsEditable="True" KeyDown="cmbVal_KeyDown"  />
             </DataTemplate>
      </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
        <DataGridTemplateColumn Header="Value" Width="100">
            <DataGridTemplateColumn.CellTemplate>
               <DataTemplate>
                <TextBox Text="{Binding ComboValue}" Name="tBoxValue" TextChanged="tBoxVale_textChanged"/>
               </DataTemplate>
           </DataGridTemplateColumn.CellTemplate>
      </DataGridTemplateColumn>
      <DataGridTemplateColumn Header="Comment" Width="200">
    <DataGridTemplateColumn.CellTemplate>
         <DataTemplate>
            <TextBox Text="{Binding Comment}"/>
             </DataTemplate>
     </DataGridTemplateColumn.CellTemplate>
   </DataGridTemplateColumn>
  </DataGrid.Columns>
 </DataGrid>      

enter image description here As shown in pic, when Combobox selected Item changes, Textbox value is changed according to SelectedItem of Combobox Now, here comes my problem. Combobox is Editable, if user enters anything (string), and presses ENTER Key, Combobox text goes to Textbox Text.

private void cmbVal_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Return)
        {               
            string s = ((ComboBox)sender).Text;
            DataGridRow row = sigGrid.ItemContainerGenerator.ContainerFromIndex(sigGrid.SelectedIndex) as DataGridRow;
            var i = 3;
            TextBox ele = sigGrid.FindName("tbValue") as TextBox;
        }

    }

And Result is: enter image description here

Mamurbek
  • 77
  • 2
  • 11
  • Can you explain why you want to access the TextBox by name? Are you trying to read the value? If yes, then you're not supposed to do it like that. Please explain in as much detail what you're trying to achieve and we might be able to help. Also, provide any relevant code that might help explaining what you're trying to do. – LightBulb Sep 24 '15 at 07:41
  • @LightBulb Thank you for your help, I updated question – Mamurbek Sep 24 '15 at 09:28

2 Answers2

2

@Mamurbek,

You could use the FindVisualDescendants function of that post :
Datagrid templatecolumn update source trigger explicit only updates first row

Using that function, you could have all textboxes for instance :

var textboxes = AccessGrid.FindAllVisualDescendants()
    .Where(elt => elt.Name == "tBoxValue" )
    .OfType<TextBox>();

Only the first for instance :

var textboxes = AccessGrid.FindAllVisualDescendants()
    .Where(elt => elt.Name == "tBoxValue" )
    .OfType<TextBox>()
    .FirstOrDefault();

Or only the 3rd using Skip and Take :

int n = 3;
var textboxes = AccessGrid.FindAllVisualDescendants()
    .Where(elt => elt.Name == "tBoxValue" )
    .OfType<TextBox>()
    .Skip(n-1)
    .Take(1);

Hope it helps

Community
  • 1
  • 1
Emmanuel DURIN
  • 4,803
  • 2
  • 28
  • 53
  • Thank you, Thank you. It is helpful. I used this way to get only one TextBox IEnumerable textBoxes = sigGrid.FindAllVisualDescendants().Where(elt => elt.Name == "tBoxValue").OfType(); textBoxes.ElementAt(selected).Text = "Text Added."; But I need to test it more and more for debugging purpose, because I was getting wrong number of textboxes. – Mamurbek Sep 25 '15 at 01:40
1

If you use bindings in your xaml, you obviously have a object used as a datacontext for your grid named grdSignal.

And from this line...

  <TextBox Text="{Binding Comment}"/>

I can see that the bound objects have a Comment property:

If you want to read or write this value, you have to locate the respective property is your data source which is bound to the grid (used a data context) and read or assign this property.

In your case, if your assign a value to this property (if it implements INotifyPropertyChanged) the TextBox will update automatically to the new value.

In summary:

  • If you use bindings, you have to read and assign from / to properties of your data classes in order to communicate with the UI. Bindings connect targets (controls in your UI) to sources (data in your data context class or view model), so there should be no need to name controls in your view.

  • If you do not use bindings, you can communicate with the UI using the code behind file and accessing elements by their names, but this is not the way it should be done in WPF (not MVVM style)

Martin
  • 5,165
  • 1
  • 37
  • 50
  • Thank you for your attention. I updated answer, could you check it one more time? Thank You!!! – Mamurbek Sep 24 '15 at 09:02
  • The column with the header `Physical value` seems to be bound to the `SelectedRaValue` property. Can you read / assign this property? – Martin Sep 24 '15 at 09:10
  • So you do not need to address the textbox by name. Is your problem now solved? – Martin Sep 24 '15 at 09:37
  • Thank You very much. I implemented as you suggested and also Emmanuel DURIN way. Both are successfull. Thank you one more time – Mamurbek Sep 25 '15 at 01:38