将元素绑定到内部UserControl数据上下文

时间:2016-09-21 13:12:38

标签: c# wpf xaml user-controls

正如标题所暗示的,我正在尝试将元素绑定到内部用户控件数据上下文,但它有点复杂。

首先,这是我的xaml视图的片段:

<TabControl Grid.Row="0" Grid.Column="1" Margin="5" TabStripPlacement="Top"
            Style="{StaticResource TabControlStyle}" FontSize="16">
        <TabItem Header="Local Settings" IsEnabled="{Binding ElementName=localSettings, Path=IsEnabled}">
            <tabViews:LocalSettingsView x:Name="localSettings" DataContext="{Binding TabsVM, Converter={StaticResource dictionaryToViewModel}, ConverterParameter={x:Static enums:TabsEnum.LocalSettings}}" />
        </TabItem>
        ... more TabItems ...
    </TabControl>

正如你所看到的,我已尝试(没有任何运气)将其与元素名称绑定,但它没有按预期工作。
我在输出窗口中收到此异常:
System.Windows.Data Error: 40 : BindingExpression path error: 'IsEnabled' property not found on 'object' ''LocalSettingsView' (Name='localSettings')'. BindingExpression:Path=IsEnabled; DataItem='LocalSettingsView' (Name='localSettings'); target element is 'TabItem' (Name=''); target property is 'IsEnabled' (type 'Boolean')
以下是相关的代码部分:
绑定属性

private Dictionary<string, ITabViewModel> _tabsVM;
    public Dictionary<string, ITabViewModel> TabsVM
    {
        get
        {
            if (_tabsVM == null)
            {
                _tabsVM = new Dictionary<string, ITabViewModel>()
                {
                    { "Network", new NetworkViewModel() },
                    { "Cru", new CRUViewModel() },
                    { "LocalSettings", new LocalSettingsViewModel() },
                    { "Connectivity", new ConnectivityViewModel() },
                    { "Security", new SecurityViewModel() },
                };
            }
            return _tabsVM;
        }
    }

转换器

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {                        
        Dictionary<string, ITabViewModel> _tabsVM = value as Dictionary<string, ITabViewModel>;
        if (_tabsVM == null)
            return null;

        string param = Enum.GetName(typeof(TabsEnum), parameter);

        ITabViewModel _selectedVM;
        bool success = _tabsVM.TryGetValue(param, out _selectedVM);
        if (success)
            return _selectedVM;
        else
            return null;
    }

最后, TabsEnum

    public enum TabsEnum
{
    LocalSettings,
    Network,
    Connectivity,
    Security,
    Cru,
}

修改

我正在添加LocalSettingsView&amp;它是ViewModel的相关部分

<UserControl x:Class="ContentTemplateTest.Views.TabViews.LocalSettingsView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/ContentTemplateTest;component/Styles/Generic.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>
<DockPanel>
    <Grid DockPanel.Dock="Top">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="4*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />                
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Grid.Column="0" Text="Hospital Name" />
        <TextBox x:Name="hospitalTextBox" Grid.Row="0" Grid.Column="1" Text="DEMO - 000000" />

        <TextBlock Grid.Row="1" Grid.Column="0" Text="Full Address" />
        <TextBox Grid.Row="1" Grid.Column="1" />

        <TextBlock Grid.Row="2" Grid.Column="0" Text="Department" />
        <TextBox Grid.Row="2" Grid.Column="1" />

        <TextBlock Grid.Row="3" Grid.Column="0" Text="Date and Time" />
        <TextBox Grid.Row="3" Grid.Column="1" Text="{Binding DateAndTime}" />

        <TextBlock Grid.Row="4" Grid.Column="0" Text="Interface Language" />
        <ComboBox Grid.Row="4" Grid.Column="1" ItemsSource="{Binding Languages}"
                          SelectedItem="{Binding SelectedInterfaceLang}"/>

        <TextBlock Grid.Row="5" Grid.Column="0" Text="Manual Language" />
        <ComboBox Grid.Row="5" Grid.Column="1" ItemsSource="{Binding Languages}"
                          SelectedItem="{Binding SelectedManualLang}"/>

        <TextBlock Grid.Row="6" Grid.Column="0" Text="Units" />
        <ComboBox Grid.Row="6" Grid.Column="1" ItemsSource="{Binding Units}"
                          SelectedItem="{Binding SelectedUnit}"/>

        <TextBlock Grid.Row="7" Grid.Column="0" Text="Video Settings" />
        <ComboBox Grid.Row="7" Grid.Column="1" ItemsSource="{Binding VideoSettings}"
                          SelectedItem="{Binding SelectedVideoFormat}"/>

        <TextBlock Grid.Row="8" Grid.Column="0" Text="Keyboard Input Language" />
        <ComboBox Grid.Row="8" Grid.Column="1" ItemsSource="{Binding Languages}"
                          SelectedItem="{Binding SelectedKeyboardLang}"/>            
    </Grid>
    <Grid VerticalAlignment="Bottom" DockPanel.Dock="Bottom">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>            
        <Button Grid.Column="0" Width="100" Height="100" Margin="50">
            <Image Source="../../src/Save.png" Width="40" Height="40" Margin="20" />
        </Button>
        <Button Grid.Column="1" Width="100" Height="100" Margin="50">
            <Image Source="../../src/Cancel.png" Width="40" Height="40" Margin="20" />
        </Button>
        <Button Grid.Column="2" Width="100" Height="100" Margin="50">
            <Image Source="../../src/Export.png" Width="40" Height="40" Margin="20" />
        </Button>
    </Grid>
</DockPanel>    

及相关财产:

        public bool IsEnabled
    {
        get { return false; }
    }

我如何实现目标?
谢谢!

1 个答案:

答案 0 :(得分:0)

非常简单的解决方案 只需将DataContext移至TabItem

即可
<TabItem Header="Local Settings" IsEnabled="{Binding IsEnabled}" 
                 DataContext="{Binding TabsVM, Converter={StaticResource dictionaryToViewModel}, ConverterParameter={x:Static enums:TabsEnum.LocalSettings}}" >
            <tabViews:LocalSettingsView />
</TabItem>