Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Silverlight选项卡项可见性未更改_Silverlight_Tabcontrol_Visibility_Silverlight 5.0_Tabitem - Fatal编程技术网

Silverlight选项卡项可见性未更改

Silverlight选项卡项可见性未更改,silverlight,tabcontrol,visibility,silverlight-5.0,tabitem,Silverlight,Tabcontrol,Visibility,Silverlight 5.0,Tabitem,我有一个TabControl,其中有许多TabItems绑定到一个ViewModel,该ViewModel具有每个TabItem可见性的属性 <sdk:TabControl> <sdk:TabItem Name="Inventory" Header="Inventory" Style="{StaticResource TabItemStyle}" Visibility="{Binding Permissions.Inventory,

我有一个TabControl,其中有许多TabItems绑定到一个ViewModel,该ViewModel具有每个TabItem可见性的属性

<sdk:TabControl>
    <sdk:TabItem Name="Inventory" Header="Inventory" 
        Style="{StaticResource TabItemStyle}"
        Visibility="{Binding Permissions.Inventory,
        Converter={StaticResource PermissiveVisibilityConverter}, 
            ConverterParameter='Viewer'}"
        DataContext="{Binding VM}" />

</sdk:TabControl>

所有选项卡项都默认为折叠的可见性。但是当VM将TabItem更改为Visible时,除非将鼠标移到控件上,否则它不会工作

即使我用一个按钮以编程方式设置可见性,它的行为也是一样的

我已经检查了VM的属性是否正在通知UI,并且它们是否已使用NotifyOnPropertyChanged。如果我把数据绑定到一个按钮的可见性上,它就可以正常工作了……只是TabItems似乎有一个bug

有没有办法让TabItem UI刷新?或者是一个工作环境


谢谢

如果更改xaml,以便首先设置DataContext,该怎么办:

 <sdk:TabItem Name="Inventory" Header="Inventory" 
    Style="{StaticResource TabItemStyle}"
    DataContext="{Binding VM}"
    Visibility="{Binding Permissions.Inventory,
    Converter={StaticResource PermissiveVisibilityConverter}, 
        ConverterParameter='Viewer'}" />

我假设Permissions.Inventory是视图模型上的一个属性,但由于您当时没有设置上下文,因此绑定似乎不应该工作


另外,如果设置了断点,并且调用了Permissions.Inventory上的getter,是否会命中转换器?

我也遇到了同样的问题,我可以使用附加的“可见性”属性而不是原始属性来克服它。在这个新属性中,我可以将该值传递给原始的“可见性”属性,如果父选项卡控件的“SelectedItem”正在折叠,请选择下一个可见选项卡项

但是,如前所述,如果加载TabControl时第一个项已折叠,则仅此可能不够。这种情况必须在TabControl本身中修复,因为测试显示,当第一次设置假“可见性”时,TabItem还没有访问其TabControl的权限。正因为如此,我还为TabControl使用了一个附加属性来纠正这个问题

完整的解决方案:

public static class TabControlExtensions
{
    /// <summary>
    /// Use this property on a TabControl to correct the behavior
    /// of selecting Collapsed TabItems.
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static bool GetSelectOnlyVisibleTabs(DependencyObject obj)
    {
        return (bool)obj.GetValue(SelectOnlyVisibleTabsProperty);
    }
    public static void SetSelectOnlyVisibleTabs(DependencyObject obj, bool value)
    {
        obj.SetValue(SelectOnlyVisibleTabsProperty, value);
    }
    public static readonly DependencyProperty SelectOnlyVisibleTabsProperty =
        DependencyProperty.RegisterAttached("SelectOnlyVisibleTabs", typeof(bool), typeof(TabControlExtensions), new PropertyMetadata(false, SelectOnlyVisibleTabsChanged));
    public static void SelectOnlyVisibleTabsChanged(object sender, DependencyPropertyChangedEventArgs args)
    {
        var tabControl = sender as TabControl;
        if (tabControl == null) return;

        if ((bool)args.NewValue)
        {
            tabControl.SelectionChanged += TabControl_SelectionChanged;
            CorrectSelection(tabControl);
        }
        else
        {
            tabControl.SelectionChanged -= TabControl_SelectionChanged;
        }
    }

    private static void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs args)
    {
        var tabControl = sender as TabControl;
        if (tabControl == null) return;

        CorrectSelection(tabControl);
    }

    public static void CorrectSelection(TabControl tabControl)
    {
        var selected = tabControl.SelectedItem as UIElement;
        if (selected == null) return;

        // If the selected element is not suposed to be visible,
        // selects the next visible element
        if (selected.Visibility == System.Windows.Visibility.Collapsed)
            tabControl.SelectedItem = tabControl.Items.OfType<UIElement>()
                .Where(e => e.Visibility == System.Windows.Visibility.Visible)
                .FirstOrDefault();
    }
}

public static class TabItemExtensions
{
    /// <summary>
    /// Use this property in a TabItem instead of the original "Visibility" to 
    /// correct the behavior of a TabControl when a TabItem's Visibility changes.
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public static Visibility GetVisibility(DependencyObject obj)
    {
        return (Visibility)obj.GetValue(VisibilityProperty);
    }
    public static void SetVisibility(DependencyObject obj, Visibility value)
    {
        obj.SetValue(VisibilityProperty, value);
    }
    public static readonly DependencyProperty VisibilityProperty =
        DependencyProperty.RegisterAttached("Visibility", typeof(Visibility), typeof(TabItemExtensions), new PropertyMetadata(Visibility.Visible, VisibilityChanged));

    public static void VisibilityChanged(object sender, DependencyPropertyChangedEventArgs args)
    {
        var tabItem = sender as TabItem;
        if (tabItem == null) return;

        var visibility = (Visibility)args.NewValue;
        if (tabItem.Visibility == visibility) return;

        tabItem.Visibility = visibility;
        if (visibility == Visibility.Visible) return;

        // Finds the tab's parent tabcontrol and corrects the selected item, 
        // if necessary.
        var tabControl = tabItem.Ancestors().OfType<TabControl>().FirstOrDefault();
        if (tabControl == null) return;

        TabControlExtensions.CorrectSelection(tabControl);
    }
}
公共静态类TabControlExtensions
{
/// 
///在TabControl上使用此属性可更正该行为
///选择折叠选项卡项的方法。
/// 
/// 
/// 
公共静态bool GetSelectOnlyVisibleTab(DependencyObject对象)
{
return(bool)obj.GetValue(SelectOnlyVisibleTabsProperty);
}
公共静态无效设置SelectOnlyVisibleTab(DependencyObject对象,布尔值)
{
对象设置值(仅选择可视选项卡属性、值);
}
公共静态只读从属属性SelectOnlyVisibleTabsProperty=
DependencyProperty.RegisterAttached(“SelectOnlyVisibleTab”、typeof(bool)、typeof(TabControlExtensions)、new PropertyMetadata(false,SelectOnlyVisibleTabsChanged));
public static void SelectOnlyVisibleTabsChanged(对象发送方,DependencyPropertyChangedEventArgs参数)
{
var tabControl=发送方作为tabControl;
if(tabControl==null)返回;
if((bool)args.NewValue)
{
tabControl.SelectionChanged+=tabControl\u SelectionChanged;
正确选择(tabControl);
}
其他的
{
tabControl.SelectionChanged-=tabControl\u SelectionChanged;
}
}
私有静态无效选项卡控件\u SelectionChanged(对象发送方,SelectionChangedEventArgs args)
{
var tabControl=发送方作为tabControl;
if(tabControl==null)返回;
正确选择(tabControl);
}
公共静态无效更正选择(TabControl TabControl)
{
var selected=tabControl.SelectedItem作为UIElement;
if(selected==null)返回;
//如果选定的图元不显示,
//选择下一个可见元素
if(selected.Visibility==System.Windows.Visibility.Collapsed)
tabControl.SelectedItem=tabControl.Items.OfType()
.Where(e=>e.Visibility==System.Windows.Visibility.Visibility)
.FirstOrDefault();
}
}
公共静态类TabItemExtensions
{
/// 
///在TabItem中使用此属性,而不是在
///更正TabItem可见性更改时TabControl的行为。
/// 
/// 
/// 
公共静态可见性GetVisibility(DependencyObject obj)
{
返回(可见性)对象获取值(可见性属性);
}
公共静态void SetVisibility(DependencyObject对象,可见性值)
{
对象设置值(VisibilityProperty,value);
}
公共静态只读从属属性VisibilityProperty=
DependencyProperty.RegisterAttached(“Visibility”、typeof(Visibility)、typeof(TabItemExtensions)、new PropertyMetadata(Visibility.Visibility、VisibilityChanged));
public static void VisibilityChanged(对象发送方,DependencyPropertyChangedEventArgs参数)
{
var tabItem=发送方作为tabItem;
if(tabItem==null)返回;
变量可见性=(可见性)args.NewValue;
if(tabItem.Visibility==可见性)返回;
tabItem.Visibility=可见性;
if(visibility==visibility.Visible)返回;
//查找选项卡的父选项卡控件并更正选定项,
//如果必要的话。
var tabControl=tabItem.祖先().OfType().FirstOrDefault();
if(tabControl==null)返回;
TabControlExtensions.CorrectSelection(tabControl);
}
}
用法:

<sdk:TabControl local:TabControlExtensions.SelectOnlyVisibleTabs="True">
        <sdk:TabItem Header="tabItem1" Visibility="Collapsed">
            <TextBlock HorizontalAlignment="Center"
                       VerticalAlignment="Center"
                       Text="TabItem1 which should not be visible (1)" />
        </sdk:TabItem>
        <sdk:TabItem Header="tabItem2">
            <TextBlock HorizontalAlignment="Center"
                       VerticalAlignment="Center"
                       Text="TabItem2 which should be visible (2)" />
        </sdk:TabItem>
        <sdk:TabItem DataContext="{Binding ViewModel}"
                     Header="tabItem3"
                     local:TabItemExtensions.Visibility="{Binding MyProperty,
                                                                 Converter={StaticResource BoolToVisibilityConverter}}">
            <TextBlock HorizontalAlignment="Center"
                       VerticalAlignment="Center"
                       Text="TabItem with binded Visibility (3)" />
        </sdk:TabItem>
    </sdk:TabControl>


您使用的SL版本是什么?Permissions属性和Inventory属性的notifying属性是否都已更改?Silverlight 5。两者都是,我检查了更新ViewModel时TabItem是否看到了更改,并且确实看到了。它只是没有更新用户界面。很奇怪!我知道Tab控件中确实有一些bug,如果不亲自查看,我唯一能建议的就是从codeplex下载工具包源代码,并尝试查看Tab控件是否在内部处理Tab项的可见性