错误:"此操作仅对已应用此模板的元素有效且#34;

时间:2016-07-29 23:21:58

标签: c# wpf telerik

我有一个包含用户控件的C#WPF应用程序:

<UserControl
        x:Name="payrollEntryControl"
        x:Class="MyNamespace.PayrollEntryControl"
        [...]
        >
    [...]
</UserControl>

在用户控件中,我有一个Telerik RadDataForm

<telerik:RadDataForm
        x:Name="payrollAddForm"
        CurrentItem="[...]"
        EditTemplate="{StaticResource myEditTemplate}"
        />

该模板包含Telerik RadGridViewButton

<telerik:RadGridView Grid.Row="0" Grid.Column="0"
        x:Name="workGridView"
        [...]
        ItemsSource="{Binding [...]}"
        >
    <telerik:RadGridView.Columns>
        [...]
    </telerik:RadGridView.Columns>
</telerik:RadGridView>
<Button Grid.Row="1" Grid.Column="0"
        Command="{Binding addWorkCommand, ElementName=payrollEntryControl}"
        >
    Add
</Button>

我希望命令可以在BeginInsert()上调用workGridView。但我似乎无法访问workGridView

我的命令,到目前为止:

private DelegateCommand addWorkCommand_ = null;
public DelegateCommand addWorkCommand
{
    get
    {
        if (this.addWorkCommand_ == null)
        {
            this.addWorkCommand_ = new DelegateCommand(
                o => addWork(o)
            );
        }

        return this.addWorkCommand_;
    }
}

private void addWork(object o)
{
    var addForm = this.payrollAddForm;
    var editTemplate = addForm.EditTemplate;
    var workGrid = editTemplate.FindName("workGridView", addForm);
}

我的问题?当我拨打editTemplate.FindName()时,我得到一个例外:

  

此操作仅对已应用此模板的元素有效。

我不明白。我从表单中获取模板。怎么不适用?

1 个答案:

答案 0 :(得分:1)

Peter Duniho的评论向我指出this回答,这解决了我的问题。

  

此方法可以帮助您:

public T FindElementByName<T>(FrameworkElement element, string sChildName) where T : FrameworkElement
{
    T childElement = null;
    var nChildCount = VisualTreeHelper.GetChildrenCount(element);
    for (int i = 0; i < nChildCount; i++)
    {
        FrameworkElement child = VisualTreeHelper.GetChild(element, i) as FrameworkElement;

        if (child == null)
            continue;

        if (child is T && child.Name.Equals(sChildName))
        {
            childElement = (T)child;
            break;
        }

        childElement = FindElementByName<T>(child, sChildName);

        if (childElement != null)
            break;
    }

    return childElement;
}
     

而且,我如何使用它,只需添加按钮,然后点击按钮

private void Button_OnClick(object sender, RoutedEventArgs e)
{
    var element = FindElementByName<ComboBox>(ccBloodGroup, "cbBloodGroup");
}
 [1]: https://stackoverflow.com/a/19907800/243563

另一种方法是将workGridView作为CommandParameter传递:

<Button Grid.Row="1" Grid.Column="0"
    CommandParameter="{Binding ElementName=workGridView}"
    Command="{Binding addWorkCommand}" >
 ....

private void addWork(object o)
{
    RadGridView grid = o as RadGridView;
    grid.BeginInsert();
}