WPF MVVM:奇怪的绑定行为

i

我有一个UserControl包含的TabControl

<UserControl x:Class="Test.MyUC"
....
         xmlns:vm="clr-namespace:Test.ViewModels"
         xmlns:ikriv="clr-namespace:IKriv.Windows.Controls.Behaviors"

...

<UserControl.Resources>
    <vm:MyUCVM x:Key="VM" />
</UserControl.Resources>

<UserControl.DataContext>
    <StaticResourceExtension ResourceKey="VM" />
</UserControl.DataContext>

<!-- Using Ivan Krivyakov's Attached Behavior -->
<TabControl ikriv:TabContent.IsCached="True"
            TabStripPlacement="Top" ItemsSource="{Binding TabList}" IsSynchronizedWithCurrentItem="True">
    <TabControl.Resources>
        <DataTemplate DataType="{x:Type vm:MyTab1VM}">
            <v:MyTab1/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type vm:MyTab2VM}">
            <v:MyTab2/>
        </DataTemplate>
    </TabControl.Resources>
...

当然,在MyUCVM,我有TabList现在,到目前为止,一切正常。

TabControl需要从某个外部源(ViewModel当然是完成)连续递归地读取数据,并将这些数据传递给View(通过Binding)进行显示时,问题就开始出现了(例如MyTab1)到目前为止,一切正常。但是,我不希望该选项卡不可见时运行,因为这样做是没有意义的。

为此,MyTab1VM需要知道关联的视图(MyTab1)是否为所选选项卡。因此,我将其连接起来:

MyTab1:
<Style TargetType="TabItem">
    <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=OneWayToSource}" />
</Style>

MyTab1VM
public static readonly DependencyProperty IsSelectedProperty =
    DependencyProperty.Register("IsSelected",
    typeof(bool),
    typeof(MyTab1VM),
    new PropertyMetadata(false, new PropertyChangedCallback(IsSelectedChanged))
    );

public bool IsSelected
{
    get
    {
        return (bool) GetValue(IsSelectedProperty);
    }
    set
    {
        SetValue(IsSelectedProperty, value);
    }
}
public static void IsSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    if (e.Property == IsSelectedProperty)
    {
        MyTab1VM vm = d as MyTab1VM ;

        vm.SetupToGetData();
    }
}
private void SetupToGetData()
{
    if (this.IsSelected)
    {
        System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();
        timer.Interval = TimeSpan.FromMilliseconds(100);
        timer.Tick += timer_Tick;
        timer.Start();
    }
}
private void timer_Tick(object sender, EventArgs e)
{
    if (this.IsSelected)
        this.MyData = ExternalSource.GetData();
    else
    {
        (sender as System.Windows.Threading.DispatcherTimer).Stop();
    }
}

不幸的是,只有当我this.IsSelected = true;MyTab1VM的构造函数中进行手动设置时,此设置才有效将其保留在构造函数中,数据不会显示在视图中。

我设置了断点并确认绑定IsSelected正确运行。甚至计时器正在运行,并且ExternalSource.GetData()正在被调用。但是this.MyData = ExternalSource.GetData();不会触发从ViewModel到View的更改。

最令人困惑的是,如果从构造函数IsSelected设置为true则会触发相同的绑定

外面有人知道这里发生了什么吗?

i

我独自完成了一些富有成效的故障排除。我输入了一个断点,SetupToGetData()并放入this.GetHashCode()了调试监视列表。当我this.IsSelected = true在构造函数中手动设置时,我意识到该SetupToGetData()方法被调用了两次,具有两个不同的哈希值。在构造函数中植入另一个断点还表明,当我切换到此选项卡时,将调用构造函数。

我决定将其移至一个新问题,因为该问题与绑定无关的可能性很高。

编辑

看来我是对的,是这个问题的根源。解决了这个问题后,这个问题也解决了。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章