Reference to a TextBox inside a DataTemplate

前端 未结 3 2054
不知归路
不知归路 2021-01-23 10:27

How do I get a reference to a TextBox that\'s only defined inside a DataTemplate (assuming that I\'ve just applied this DataTemplate to some cell in a grid).

So far I\'m

相关标签:
3条回答
  • 2021-01-23 10:44

    I agree with Justin.

    But if for some reason binding to some property is problematic and you still need reference to a control inside data template in SILVERLIGHT ( above solution is suitable for WPF components ) you can do as follow:

    TextBox textBox = null;
    
       if (datagrid.SelectedItem != null)
          textBox = datagrid.Columns[1].GetCellContent(datagrid.SelectedItem) as TextBox;
    
       if (textBox != null)
          MessageBox.Show(textBox.Text);
    
    0 讨论(0)
  • 2021-01-23 10:49

    Sorry, but you're doing it wrong.
    There's no good reason why you should have a reference to elements inside a DataTemplate IMO. Moreover, there's really no good reason for you to ever register for a Control Event.

    As part of the MVVM architecture we started looking at Data and Interactions.
    On the Data side - everything is databound to the ViewModel.
    On the interactions side - Using ICommands all events are wired up for commands.

    So, in your TextBox example - why are you listening to textbox events? Use TwoWay DataBinding to learn when TextBox text change.
    In another example in which events are justified, like button.Click? Use Button.Command="{Binding myCommand}" to have commands handle events.

    The reason you're running into issues is because you're trying to force a round peg in a square hole.

    -- Justin

    0 讨论(0)
  • 2021-01-23 11:05

    For getting the reference of a control inside a Data Template, handling the event and then using the sender is one of the available option. There is one more option that you can try:

    in .xaml:

        <toolkit:DataGrid Name="datagrid" Margin="0,0,0,28" AutoGenerateColumns="False">
            <toolkit:DataGrid.Columns>
                <toolkit:DataGridTextColumn Header="First Name" Binding="{Binding FirstName}"/>
                <toolkit:DataGridTemplateColumn Header="Last Name">
                    <toolkit:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox Text="{Binding LastName}"/>
                        </DataTemplate>
                    </toolkit:DataGridTemplateColumn.CellTemplate>
                </toolkit:DataGridTemplateColumn>
            </toolkit:DataGrid.Columns>
        </toolkit:DataGrid>
        <Button Height="22" VerticalAlignment="Bottom" Click="Button_Click" />
    

    in .xaml.cs

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            InitializeMouseHandlersForVisual(datagrid);
        }
    
        public void InitializeMouseHandlersForVisual(Visual visual)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
            {
                Visual childVisual = (Visual) VisualTreeHelper.GetChild(visual, i);
                if (childVisual is TextBox)
                    MessageBox.Show("textbox Found");
                // Recursively enumerate children of the child visual object.
    
                InitializeMouseHandlersForVisual(childVisual);
            }
        }
    

    Hope this helps!!

    Edit:

    if you want to use x:Name then also you need to at least get the ContentPresenter and for getting ContentPresenter you need to go through the element tree. The updates you need to make are:

    in .xaml:

        <DataTemplate>
            <TextBox x:Name="text" Text="{Binding LastName}"/>
         </DataTemplate>
    

    in .xaml.cs

        public void InitializeMouseHandlersForVisual(Visual visual)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
            {
                Visual childVisual = (Visual) VisualTreeHelper.GetChild(visual, i);
                ContentPresenter myContentPresenter = childVisual as ContentPresenter;
                if (myContentPresenter != null)
                {
                    // Finding textBlock from the DataTemplate that is set on that ContentPresenter
                    DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
                    if (myDataTemplate != null)
                    {
                        TextBox myTextBox = (TextBox)myDataTemplate.FindName("text", myContentPresenter);
                        MessageBox.Show("textbox Found");
                    }
                }
                InitializeMouseHandlersForVisual(childVisual);
            }
        }
    

    Hope this helps!!

    0 讨论(0)
提交回复
热议问题