Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
272 views
in Technique[技术] by (71.8m points)

c# - Bind visibility to checkable menu item shows error "Service provider is missing the INameResolver service" in WPF

I am trying to show/hide columns of a datagrid via a context menu. I was trying to use bindings for it, with this XAML:

<Grid>
    <DataGrid AutoGenerateColumns="False" Name="dataGrid1">
        <DataGrid.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Show Column 1" IsCheckable="True" 
                    x:Name="showcol1" IsChecked="True" />
                <MenuItem Header="Show Column 2" IsCheckable="True"
                    x:Name="showcol2" IsChecked="False" />
            </ContextMenu>
        </DataGrid.ContextMenu>
        <DataGrid.Columns>
            <DataGridTextColumn Header="Col 0" />
            <DataGridTextColumn Header="Col 1" 
                Visibility="{Binding ElementName=showcol1, 
                Converter={StaticResource BooleanToVisibilityConverter},
                Path=IsChecked}" />
            <DataGridTextColumn Header="Col 2" 
                Visibility="{Binding ElementName=showcol2, 
                Converter={StaticResource BooleanToVisibilityConverter},
                Path=IsChecked}" />
        </DataGrid.Columns>
    </DataGrid>
</Grid>

I even experimented with the other options, such as BindsDirectlyToSource=True and UpdateSourceTrigger=PropertyChanged. However, the columns do not change their visibility when I check/uncheck the menuitems. What am I doing wrong? Is this actually possible in pure XAML?

In this question, the answer uses x:Reference. I tried that too but received the error

Service provider is missing the INameResolver service.

Google told me that this is a bug in VS2010? What can I do to resolve this? Or is my best shot to switch to VS2012?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is the explanation from Adam Nathan's WPF 4 unleashed book (I advise everyone to read):

The x:Reference markup extension is often mistakenly associated with the XAML2009 features that can only be used from loose XAML at the time of this writing. Although x:Reference is a new feature in WPF 4, it can be used from XAML2006 just fine as long as your project is targeting version 4 or later of the .NET Framework. One glitch is that the XAML designer in Visual Studio 2010 doesn't properly handle x:Reference, so it gives the following design-time error that you can safely ignore: Service provider is missing the INameResolver service.

In any case, this message can be ignored. For my Visual Studio 2010, it sometimes appears, sometimes not.

EDIT:

I found one more quote (source), but they do not offer specific solutions:

When using {x: Reference } as the Target of a WPF Label, the Visual Studio designer throws an InvalidOperationException exception with the message "Service provider is missing the INameResolver service." The project will compile and execute without any issues, but the Design canvas where the x: Reference appears will be disabled because of the exception. As of this book's writing, this is a known issue and should be resolved sometime in the future.

Here, author specifically explains the problem, and writes that sent the bug report to Microsoft.

BooleanToVisibilityConverter

<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>

DataGrid XAML

<DataGrid AutoGenerateColumns="False" Name="dataGrid1">
    <DataGrid.ContextMenu>
        <ContextMenu>
            <MenuItem x:Name="showcol1" Header="Show Column 1" IsCheckable="True" IsChecked="True" />
            <MenuItem x:Name="showcol2" Header="Show Column 2" IsCheckable="True" IsChecked="False" />
        </ContextMenu>
    </DataGrid.ContextMenu>

    <DataGrid.Columns>
        <DataGridTextColumn Header="Col 0" />

        <DataGridTextColumn Header="Col 1" Visibility="{Binding Source={x:Reference Name=showcol1}, Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}}" />

        <DataGridTextColumn Header="Col 2" Visibility="{Binding Source={x:Reference Name=showcol2}, Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}}" />
    </DataGrid.Columns>
</DataGrid>    

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...