将用户控件的 属性 绑定到数据

Binding property of usercontrol to data

我不确定要使用正确的术语。大约一年前,我创建了一个 Windows 商店应用程序,主页是由 Visual Studio 创建的,我从未对其进行太多更改。它使用工作正常的视图模型,但我不知道如何解决问题。无论如何...

该页面使用 GridView 来显示 CollectionViewSource 元素的内容以引用 ObservableCollection。这一切都很好。其中一个数据项的 DataTemplate 现在看起来像这样:

<DataTemplate x:Key="TopImageTileTemplate">
    <Grid MinHeight="135" Width="350" Margin="0" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="135"/>
        </Grid.RowDefinitions>

        <TextBlock Text="{Binding Path=ImagePath}" FontSize="33"/>

        <usercontrols:WaitingImageControl SourcePath="{Binding Path=ImagePath}" Grid.Row="0" Width="350" Height="165" HorizontalAlignment="Center" VerticalAlignment="Stretch" AutomationProperties.Name="{Binding Title}" Visibility="{Binding TypeDescription, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource TextToVis}}"/>

        <usercontrols:WaitingImageControl SourcePath="XXX" Grid.Row="0" Width="350" Height="165" HorizontalAlignment="Center" VerticalAlignment="Stretch" AutomationProperties.Name="{Binding Title}" Visibility="{Binding TypeDescription, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource TextToVis}}"/>

        <ProgressRing Opacity="0.5" Foreground="#FF8A57FF" Grid.Row="0" Name="TheProgressControl" IsActive="True" Height="32" Width="32" Background="Transparent" VerticalAlignment="Center" HorizontalAlignment="Center"/>

        ...

    </Grid>
</DataTemplate>

我遇到的问题是,此数据项包含一个名为 ImagePath 的字符串,我想将其传递给 WaitingImageControl 用户控件,但它无法正常工作。 TextBlock 工作正常,文本显示 ImagePath 字符串也很好。第二个 WaitingImageControl 工作正常,处理 SourcePath 的代码也确实通过了 "XXX"。但是第一个 WaitingImageControl 永远不会从数据项中传递 ImagePath 值。

这是某种绑定问题,我对绑定知之甚少,以至于我什至无法确定要尝试什么(或在这个问题中显示什么)。考虑到 TextBlock 绑定有效并且第二个 WaitingImageControl 绑定有效,我不知所措。

这是 SourcePath 属性 的 WaitingImageControl 代码:

    public static readonly DependencyProperty SourcePathProperty = 
        DependencyProperty.Register("SourcePath", typeof(string), typeof(WaitingImageControl), new PropertyMetadata(""));

    public string SourcePath
    {
        get { return m_SourcePath; }
        set 
        {
            if( string.IsNullOrEmpty( value ) )
                return;

            m_SourcePath = value;
            ResourcesStore Store = new ResourcesStore();
            if( Store.Count() == 0 )
            {
                var IgnoreMe = CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync( CoreDispatcherPriority.Normal, () =>
                {
                    // No progress and no image...
                    TheProgressControl.Visibility = Visibility.Collapsed;
                    TheImage.Visibility = Visibility.Collapsed;
                } );
                return;
            }
            ResourceItem Item = Store.getItemByFilename( m_SourcePath );

            LocalInboxService.Instance.InboxStatusChanged -= InboxStatusChanged;
            InboxStatusChanged( null );
            LocalInboxService.Instance.InboxStatusChanged += InboxStatusChanged;
        }
    }

代码应该在下载图像后显示 Image 元素并隐藏 ProgressRing 元素。

当 ImagePath 自动传递给 TextBlock 时,数据项的代码再次正常工作:

    public string ImagePath
    {
        get
        {
             return this._imagePath;
        }

        set
        {
            this._imagePath = value;
            this.SetProperty(ref this._imagePath, value);
       }
    }

感谢任何帮助使 ImagePath 到 SourcePath 绑定(如下)工作:

    <usercontrols:WaitingImageControl SourcePath="{Binding Path=ImagePath}"
     Grid.Row="0" Width="350" Height="165" HorizontalAlignment="Center"
     VerticalAlignment="Stretch" AutomationProperties.Name="{Binding Title}"
     Visibility="{Binding TypeDescription, RelativeSource={RelativeSource
     Mode=TemplatedParent}, Converter={StaticResource TextToVis}}"/>

经过几个小时的搜索,我找到了 Whosebug 对类似问题的回答。答案是向 Propertymetadata 添加一个 PropertyChanged 函数。我还不确定这到底是什么意思,或者为什么只在这里需要它,但它可以正常工作:

    public static readonly DependencyProperty SourceImageResourceIdProperty = 
        DependencyProperty.Register("SourceImageResourceId", typeof(string), typeof(WaitingImageControl), new PropertyMetadata( string.Empty, OnSourcePathPropertyChanged ));


    private static void OnSourcePathPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        (d as WaitingImageControl).SourceImageResourceId = e.NewValue.ToString();
    }

调用 OnSourcePathPropertyChanged 函数并按应有的方式设置 属性。

现在我只希望它不是真正解决这个问题的其他二十个实验之一!