Silverlight MVVM Prism和OpenFileDialog

时间:2009-07-17 15:50:27

标签: silverlight silverlight-3.0 mvvm prism

我目前正在开发SilverLight 3应用程序。我正在使用MVVM Pattern和Prism。我有一切工作,除了以下项目。在我的一个观点中,我必须使用OpenFileDialog。我试图在ViewModel中执行此操作,仅发现SilverLight的安全模型禁止它,因为它只允许用户启动。我已经将OpenFileDialog代码移动到View的代码隐藏。这是我的问题。虽然我已经绑定到设置为TwoWay的源代码,但它没有在我的ViewModel中触及属性的setter。

带绑定的图像控制示例:

<Image x:Name="imgCard" Height="283" Width="463" Canvas.Left="8" Canvas.Top="8" OpacityMask="White" Source="{Binding Path=CardImage, Mode=TwoWay}"/>

用户使用的按钮:

<Button x:Name="btnUpload" Height="20" Width="122" Canvas.Left="8" Canvas.Top="319" Content="Upload Image" Click="btnUpload_Click" />

点击活动:

private void btnUpload_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "PNG Files(*.png)|*.png";

            ofd.ShowDialog();
            using (Stream stream = ofd.File.OpenRead())
            {
                BitmapImage image = new BitmapImage();
                image.SetSource(stream);
                imgCard.Source = image;
            }
        }

我的ViewModel正在实现INotifyPropertyChanged并具有以下属性。

BitmapSource CardImage
            {
                get
                {
                    return _imageSource;
                }
                set
                {
                    _imageSource = value;
                    NotifyPropertyChanged("CardImage");
                }
            }

如果我在Setter上设置了一个断点。它从来没有打过它。

2 个答案:

答案 0 :(得分:1)

至少在Silverlight 2中,我认为以下规则可以解释为什么你会看到这种行为。 “如果绑定了依赖项属性,并且在代码中将属性显式设置为值,则删除绑定。” (source

Silverlight 3可能已经改变了吗?在那种情况下,我没有任何建议。

答案 1 :(得分:0)

好的,这是一个黑客,但它的工作原理。因为我必须从UI激活OpenFileDialog,所以我可以直接将控件更新到DataContext以更新属性。这样做仍然可以按照我的预期呈现UI。

注意:HACK直到找到更好的方法。

private void btnUpload_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "PNG Files(*.png)|*.png";

            ofd.ShowDialog();
            using (Stream stream = ofd.File.OpenRead())
            {
                BitmapImage image = new BitmapImage();
                image.SetSource(stream);
                BitmapSource b = image;

                //HACK: This works but now I'm tethered a bit.  This updates the context property CardImage.
                ((DesignerViewModel) this.DataContext).CardImage = b;
                //imgCard.Source = b;
            }
        }