首页 > 解决方案 > WPF TabControl 绑定错误

问题描述

我有以下 XAML ......

<TabControl Grid.Row="0" Grid.Column="1" Grid.RowSpan="2"
                    Name="customerTab"
                    ItemsSource="{ Binding DetailViewModels }" 
                    SelectedItem="{Binding SelectedDetailViewModel, Mode=TwoWay}"
                    TabStripPlacement="Top">
            <TabControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Title}" />
                        <TextBlock Text="*" Visibility="{Binding HasChanges, Converter={StaticResource BooleanToVisibilityConverter}}" />
                        <Button Command="{Binding CloseCommand}" Style="{StaticResource closeButtonStyle}" />
                    </StackPanel>
                </DataTemplate>
            </TabControl.ItemTemplate>
        </TabControl>

基本上,我有一个列表视图,我可以在其中单击记录以查看详细信息。详细记录显示在选项卡控件中。

您可以看到我有一个按钮,该按钮绑定到关闭选项卡的命令。

当我关闭选项卡时,显示以下绑定错误...

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.TabControl', AncestorLevel='1''. BindingExpression:Path=TabStripPlacement; DataItem=null; target element is 'TabItem' (Name=''); target property is 'NoTarget' (type 'Object')

我不完全确定这个问题。这是否意味着细节视图模型在关闭时无法爬回层次结构到选项卡控件?

实际的应用程序按设计工作,我只想解决这个错误,所以每次关闭标签时它都不会出现。

CloseCommand 是一个委托命令。这是该代码及其运行的方法。

public DelegateCommand CloseCommand { get; private set; }
CloseCommand = new DelegateCommand(OnClose);
public void OnClose()
        {
            OnTabClosed?.Invoke(InstanceId);
        }

OnTabClos​​ed 是关闭选项卡的操作,InstanceId 只是详细视图模型的 GUID。

我确实在网上搜索并找到了隐藏消息的方法,但我不愿意这样做,因为害怕隐藏更多合法的绑定错误。

我该如何解决?调试的最佳方法是什么?

编辑 这是处理选项卡项关闭的代码...

private void HandleTabClosed(Guid instanceId)
        {
            DetailViewModels.Remove(DetailViewModels.First(vm => vm.InstanceId == instanceId));
        }

标签: c#wpfxaml.net-core

解决方案


我刚刚进行了测试,没有发现任何错误,但我做的有点不同,所以希望对你有好处:

在 XAML 中,我对按钮使用“标记”(在使用模板时非常有用)。

拿你的代码,那将是这样的:

<TabControl Grid.Row="0" Grid.Column="1" Grid.RowSpan="2"
                    Name="customerTab"
                    ItemsSource="{ Binding DetailViewModels }" 
                    SelectedItem="{Binding SelectedDetailViewModel, Mode=TwoWay}"
                    TabStripPlacement="Top">
            <TabControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Title}" />
                        <TextBlock Text="*" Visibility="{Binding HasChanges, Converter={StaticResource BooleanToVisibilityConverter}}" />
                        <Button  Content="X" Click="Button_Click" Tag="{Binding InstanceId}" />
                    </StackPanel>
                </DataTemplate>
            </TabControl.ItemTemplate>
        </TabControl>

然后在我的“OnClick”事件中,我将查看我可以删除哪个实例,然后将其删除:

private void Button_Click(object sender, RoutedEventArgs e)
{
    Button item = (Button)sender;
    long instanceId = (long)item.Tag;
    GroupResults selectedGroup = this.MyFullList.FirstOrDefault(x => x.InstanceId == instanceId);
    if(selectedGroup!=null)
    {
        this.MyFullList.Remove(selectedGroup);
    }
}

这和你做的不太一样,但它工作得很好。我在处理模板时总是使用标签,直到现在从未遇到任何问题。


推荐阅读