从UserControl.Resources中的ControlTemplate访问文本框

时间:2014-01-31 14:21:19

标签: c# wpf controltemplate

我有一个如下定义的控件模板:

<UserControl.Resources>
 <ControlTemplate TargetType="{x:Type DataGrid}"  x:Key="inputItemsControlTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="120"/>
                <ColumnDefinition Width="200"/>
                <ColumnDefinition Width="20"/>
                <ColumnDefinition Width="200"/>
            </Grid.ColumnDefinitions>
            <Grid Grid.Column="0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="25" />
                    <RowDefinition Height="25" />
                    <RowDefinition Height="25" />
                </Grid.RowDefinitions>
                <Label Grid.Row="1" Content="{DynamicResource UCodeStr}" HorizontalAlignment="Left" VerticalAlignment="Bottom" Height="27" />
                <TextBox Name="txtUCode" Grid.Row="2" Height="23" HorizontalAlignment="Left" VerticalAlignment="Bottom"  Width="100" Text="{Binding UCode, UpdateSourceTrigger=PropertyChanged}" />
            </Grid>
            <Grid Grid.Column="1">
                <Grid.RowDefinitions>
                    <RowDefinition Height="25" />
                    <RowDefinition Height="25" />
                    <RowDefinition Height="25" />
                    <RowDefinition Height="25" />
                    <RowDefinition Height="25" />
                </Grid.RowDefinitions>
                <Label Grid.Row="1" Content="{DynamicResource GoodStr}" HorizontalAlignment="Left" VerticalAlignment="Bottom" Height="27"/>
                <ComboBox Grid.Row="2" Height="23" Width="189" HorizontalAlignment="Left"  Name="cbGoods" ItemsSource="{Binding Path=Goods}"  SelectedItem="{Binding Path= Good, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Name" IsEditable="True" IsTextSearchEnabled="True" TextSearch.TextPath="Name" />
                <Label Grid.Row="3" Content="{DynamicResource InputPriceStr}" HorizontalAlignment="Left" Name="lblInputPrice" VerticalAlignment="Bottom" Height="27"/>
                <TextBox Name="txtInputPrice" Grid.Row="4" TextAlignment="Right" Height="23" Width="189" HorizontalAlignment="Left" VerticalAlignment="Bottom" Text="{Binding Path= InputPrice, UpdateSourceTrigger=PropertyChanged,  ValidatesOnDataErrors=True, NotifyOnValidationError=True, StringFormat='N2'}" />                   
            </Grid>
            <Grid Grid.Column="3">
                <Grid.RowDefinitions>
                    <RowDefinition Height="25" />
                    <RowDefinition Height="25" />
                    <RowDefinition Height="25" />
                    <RowDefinition Height="25" />
                    <RowDefinition Height="25" />
                    <RowDefinition Height="25" />
                </Grid.RowDefinitions>
                <Label Grid.Row="1" Content="{DynamicResource AmmountStr}" HorizontalAlignment="Left" Name="lblAmmount" VerticalAlignment="Bottom" Height="27"/>
                <TextBox Name="txtAmmount" TextAlignment="Right"  Grid.Row="2" Height="23" Width="189" HorizontalAlignment="Left" VerticalAlignment="Bottom" Text="{Binding Path=Amount,  ValidatesOnDataErrors=True, NotifyOnValidationError=True,  UpdateSourceTrigger=PropertyChanged, StringFormat='N2'}" />                   
                <Label Grid.Row="3" Content="{DynamicResource SuggestedPriceStr}" HorizontalAlignment="Left" Name="lblSuggestedPrice" VerticalAlignment="Bottom" Height="27"/>
                <TextBox Name="txtSuggestedPrice" Grid.Row="4" TextAlignment="Right" Height="23" Width="189" HorizontalAlignment="Left" VerticalAlignment="Bottom" Text="{Binding Path= SuggestedPrice,  ValidatesOnDataErrors=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged, StringFormat='N2'}" />
                <CheckBox Grid.Row="5" Name="cbHasVatDeduction"  IsChecked="{Binding Path=HasVatDeduction}" />
            </Grid>
        </Grid>
    </ControlTemplate>
</UserControl.Resources>

我在codebehind中将此模板实现为datagrid。我想访问文本框“txtUCode”并将焦点设置为它。我试过这样:

InputDocItemsDataGrid.Template = (ControlTemplate)this.FindResource("inputItemsControlTemplate");
        TextBox txtUCode = (TextBox)InputDocItemsDataGrid.Template.FindName("txtUCode", InputDocItemsDataGrid);
        txtUCode.Focus();

但我的txtUCode总是空的。怎么做?

1 个答案:

答案 0 :(得分:1)

原则,你的代码很好。但是在分配这样的模板时:

InputDocItemsDataGrid.Template = (ControlTemplate)this.FindResource("inputItemsControlTemplate");

加载控件后,即元素布局,渲染并准备好进行交互时,可以访问其元素。

所以试试这个例子:

XAML

<Window x:Class="SampleDataGrid.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        Loaded="Window_Loaded"
        ContentRendered="Window_ContentRendered">

    <Window.Resources>
        <ControlTemplate x:Key="inputItemsControlTemplate" TargetType="{x:Type DataGrid}">
            <Grid>
             ....        
            </Grid>
       </ControlTemplate>
    </Window.Resources>

    <Grid>
        <DataGrid Name="InputDocItemsDataGrid" />
    </Grid>
</Window>

Code-behind

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    InputDocItemsDataGrid.Template = (ControlTemplate)this.FindResource("inputItemsControlTemplate");
}

private void Window_ContentRendered(object sender, EventArgs e)
{            
    TextBox txtUCode = (TextBox)InputDocItemsDataGrid.Template.FindName("txtUCode", InputDocItemsDataGrid);
    txtUCode.Focus();
}

首先,它调用Window_Loaded事件,然后调用Window_ContentRendered

或者像这样:

XAML

<Grid>
    <DataGrid Name="InputDocItemsDataGrid" Loaded="InputDocItemsDataGrid_Loaded" />

    <Button Content="Test" HorizontalAlignment="Left" VerticalAlignment="Bottom" Click="Button_Click" />
</Grid>

Code-behind

private void InputDocItemsDataGrid_Loaded(object sender, RoutedEventArgs e)
{
    InputDocItemsDataGrid.Template = (ControlTemplate)this.FindResource("inputItemsControlTemplate");
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    TextBox txtUCode = (TextBox)InputDocItemsDataGrid.Template.FindName("txtUCode", InputDocItemsDataGrid);
    txtUCode.Focus();
}