use textbox in column header - c# wpf

2019-09-14 15:35发布

问题:

I have a textbox and a button in my columnheader. The textbox should be collapsed until i press the button. The problem is i can't access the textbox programmaticly.

I tried tbTest.Visibility = Visibility.Visible; but it shows the following error:

"The name 'tbTest' does not exist in the current context"

I also need tbTest.Text and it doesnt work.


Here's my code:

<DataGridTextColumn.HeaderStyle>
                        <Style TargetType="DataGridColumnHeader">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="DataGridColumnHeader">
                                        <Grid>
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="auto"></ColumnDefinition>
                                                <ColumnDefinition Width="*"></ColumnDefinition>
                                                <ColumnDefinition Width="auto"></ColumnDefinition>
                                                <ColumnDefinition Width="auto"></ColumnDefinition>
                                            </Grid.ColumnDefinitions>

                                            <ContentPresenter />


                                            <Label Grid.Column="0" Padding="5 0" Content="Gruppe" VerticalAlignment="Center" Cursor="Hand" Foreground="White"/>

                                            <TextBox x:Name="tbTest" Grid.Column="1" Width="150"  Visibility="Collapsed" TextChanged="tbTest_TextChanged"></TextBox>

                                            <Button Grid.Column="2" x:Name="btnFilterGroup" Style="{StaticResource MyButton}" Width="16" Height="16" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0 0 10 0" Click="btnFilterGroup_Click">
                                                <Button.Background>
                                                    <ImageBrush ImageSource="Resources/filter.png"/>
                                                </Button.Background>
                                            </Button>


                                            <Thumb x:Name="PART_RightHeaderGripper" Grid.Column="3" HorizontalAlignment="Right" Width="2" BorderThickness="0.6" 
                                                   BorderBrush="{Binding VerticalGridLinesBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" Cursor="SizeWE"/>
                                        </Grid>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </DataGridTextColumn.HeaderStyle>

回答1:

You can't access the textbox which is used inside the datagrid using it's name. You have to use the following code to access the textbox on button click.

<DataGrid HorizontalAlignment="Left" Margin="28,152,0,0" VerticalAlignment="Top" Height="132" Width="436">
            <DataGrid.Columns>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.HeaderStyle>
                        <Style TargetType="DataGridColumnHeader">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="DataGridColumnHeader">
                                        <Grid>
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="auto"></ColumnDefinition>
                                                <ColumnDefinition Width="*"></ColumnDefinition>
                                                <ColumnDefinition Width="auto"></ColumnDefinition>
                                                <ColumnDefinition Width="auto"></ColumnDefinition>
                                            </Grid.ColumnDefinitions>

                                            <ContentPresenter />


                                            <Label Grid.Column="0" Padding="5 0" Content="Gruppe" VerticalAlignment="Center" Cursor="Hand" Foreground="White"/>

                                            <TextBox x:Name="tbTest" Grid.Column="1" Width="150"  Visibility="Hidden" TextChanged="tbTest_TextChanged" Loaded="tbTest_Loaded"></TextBox>

                                            <Button Grid.Column="2" x:Name="btnFilterGroup" Width="16" Height="16" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0 0 10 0" Click="btnFilterGroup_Click">

                                            </Button>


                                            <Thumb x:Name="PART_RightHeaderGripper" Grid.Column="3" HorizontalAlignment="Right" Width="2" BorderThickness="0.6" 
                                                   BorderBrush="{Binding VerticalGridLinesBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" Cursor="SizeWE"/>
                                        </Grid>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </DataGridTemplateColumn.HeaderStyle>
                </DataGridTemplateColumn>
                <DataGridTextColumn Header="Active"></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>

Now, add the following code to the loaded event of the textbox to get the instance of it.

private void tbTest_Loaded(object sender, RoutedEventArgs e)
        {
            tblBox = (sender as TextBox);
        }

Finally, add the following code to the button click event to change the visibility of the textbox.

private void btnFilterGroup_Click(object sender, RoutedEventArgs e)
        {
            tblBox.Visibility = Visibility.Visible;
        }

Hope this helps your need.



回答2:

You can do one of two things, if you want to access the visibility in your view model, create a visibility property then bind to it from your xaml. Alternatively you can access the text box's visibility in the code behind (xaml.cs) where tbTest.Visibility would work.

This I believe to be the standard practice and would work identically for accessing the text on the textbox as well - Create a string property on the view model and bind using similar code to below.

Text="{Binding txtBox1String, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"