我正在为 Metro UI 开发 ImagePicker 用户控件。它的原理很简单:它显示一个图像,当点击该图像时,会打开一个文件对话框,允许更改当前图像。为了实现这一点,用户控件只需公开一个 ImageSource 属性即可将包装的图像绑定(bind)到该属性。
<local:ImagePicker Source="{Binding PictureUri, Mode=TwoWay}"/>
启动时,绑定(bind)工作正常,并显示我的 View 模型提供的 PictureUri 属性中的图片。问题是,当我点击图像并选择一张新图像时,会显示新图像,但尽管采用了 TwoWay 绑定(bind)模式,但绑定(bind)值不会在我的 View 模型中更新。我相信这个问题来 self 的用户控制代码,但我不明白为什么当它实际传播到包装图像时,该值没有传播到 View 模型......
这是 XAML 部分。
<UserControl x:Name="ImagePickerUserControl"
x:Class="ImageUserControl.ImagePicker"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid x:Name="ImagePickerRootGrid" Background="Gray">
<Image Source="{Binding Source, ElementName=ImagePickerUserControl}"/>
</Grid>
</UserControl>
还有代码部分,抱歉有点长,但我相信这里的一切都很重要。
public sealed partial class ImagePicker : UserControl
{
public ImagePicker()
{
this.InitializeComponent();
// Hookup event to handle when the control is tapped
this.Tapped += ImagePicker_Tapped;
}
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register("Source", typeof(ImageSource), typeof(ImagePicker),
new PropertyMetadata(null, new PropertyChangedCallback(ImagePicker.OnSourceChanged)));
public ImageSource Source
{
get
{
return (ImageSource)this.GetValue(ImagePicker.SourceProperty);
}
set
{
this.SetValue(ImagePicker.SourceProperty, value);
}
}
private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// Update Visual State
}
private async void ImagePicker_Tapped(object sender, TappedRoutedEventArgs e)
{
// Pick up a new picture
FileOpenPicker filePicker = new FileOpenPicker();
filePicker.FileTypeFilter.Add(".jpg");
filePicker.FileTypeFilter.Add(".jpeg");
filePicker.FileTypeFilter.Add(".png");
var pngFile = await filePicker.PickSingleFileAsync();
// If the user picked up a file
if (pngFile != null)
{
BitmapImage bitmap = new BitmapImage();
await bitmap.SetSourceAsync(await pngFile.OpenReadAsync());
// Update the source image
this.Source = bitmap;
}
}
}
我相信这个问题只是我的一个错误,但我无法理解这里发生了什么。如果您想尝试运行该项目并更好地查看代码,我已将其上传并在 SkyDrive 上共享:ImageUserControl
感谢您耐心阅读这么长的帖子。
最佳答案
两种方式绑定(bind)不起作用,因为您的依赖项属性的类型为 ImageSource
,而 View 模型属性的类型为 Uri
。绑定(bind)无法将 ImageSource
转换为 Uri
,因此未设置该值。您的用户控件上需要一个 Uri
类型的属性才能使双向绑定(bind)起作用。
编辑:
如果您仅将依赖属性更改为其他类型,则当用户选择您的应用在没有选择器的情况下无法访问的文件时,内部图像将不再显示。您的应用只能使用返回的 StorageFile
来访问此类文件,而不是使用其绝对路径。在控件内部,您可以通过使用两个依赖属性来解决这个问题:ImageSource
就像现在一样用于显示内部图像,Uri
用于返回路径。由于您将绑定(bind)到第二个,因此您需要添加一个回调,当“Uri”从外部发生更改时,该回调将设置 ImageSource
属性。
根据您想要对用户控件之外的结果执行的操作,这对您来说可能仍然不够好。如果您想访问那里的文件,您需要返回一个 StorageFile
或将该文件放入 FutureAccessList 中。并返回 token 。
关于c# - XAML:用户控件未将更改传播到绑定(bind)源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14015459/