#c# #silverlight #xaml #windows-phone-7
#c# #silverlight #xaml #windows-phone-7
Вопрос:
Мне успешно удалось привязать изображения, хранящиеся в изолированном хранилище, к элементам «Изображения» внутри списка, определенного в XAML, без каких-либо проблем.
Что я сделал, так это использовал свойство, которое сохраняло имя и местоположение изображения в изолированном хранилище, и IValueConverter, чтобы фактически открыть файл и получить его поток.
Я удивлен, увидев, что я не могу сделать это в новом XAML с еще более простой настройкой. Все, что у меня есть, это:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.Resources>
<c:BinaryToImageSRCConverter x:Key="imageConverter" />
</Grid.Resources>
<Image Name="TheImage" Source="{Binding PhotoName, Converter={StaticResource imageConverter}}" Width="430" Height="430" VerticalAlignment="Center" Stretch="UniformToFill">
</Image>
</Grid>
и это то, что у меня есть в представлении модели:
public string PhotoName { get; set; }
PhotoName = "Images\0.jpg";
Путь и имя файла указаны правильно, поэтому проблема «не найти файл» не является проблемой.
Моя проблема в том, что метод Convert моего IValueConverter никогда не вызывается.
Как я упоминал ранее, я успешно использую этот конвертер в другом XAML (в том же проекте), и все работает правильно. Единственное отличие заключается в том, что я привязываюсь к изображению, используемому ListBox.
Любые идеи или подсказки относительно того, почему метод Convert моего IValueConverter не вызывается в этом сценарии?
Спасибо!
Вот что я пробовал:
- Реализация INotifyPropertyChanged:
public class PhotoNameClass : INotifyPropertyChanged { public string PhotoNameValue = string.Empty; public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } public string PhotoName { get { return this.PhotoNameValue; } set { if (value != this.PhotoNameValue) { this.PhotoNameValue = value; NotifyPropertyChanged("PhotoName"); } } } }
Вот как я присвоил свойство:
public partial class ShowContent : PhoneApplicationPage
{
PhotoNameClass photoClass = new PhotoNameClass();
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
photoClass.PhotoName = "Images\0.jpg";
base.OnNavigatedTo(e);
}
- Using DependencyProperty
public partial class ShowContent : PhoneApplicationPage
{
// PhotoNameClass photoClass = new PhotoNameClass();public string PhotoName { get { return (string)GetValue(PhotoNameProperty); } set { SetValue(PhotoNameProperty, value); } } public static readonly DependencyProperty PhotoNameProperty = DependencyProperty.Register("PhotoName", typeof(string), typeof(ShowContent), new PropertyMetadata("")); protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) { PhotoName = "Images\0.jpg"; }
Here are the relevant parts of the XAML:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.Resources>
<c:BinaryToImageSRCConverter x:Key="imageConverter" />
</Grid.Resources>
<Image Name="TheImage" Source="{Binding PhotoName, Converter={StaticResource imageConverter}}" Width="430" Height="430" VerticalAlignment="Center" Stretch="UniformToFill">
</Image>
</Grid>
где c определяется как:
xmlns:c="clr-namespace:ImageApplication"
Спасибо.
Обновить
Я использую реализацию INotifyPropertyChanged, чтобы предоставить доступ к моей собственности.
Я изменил код XAML на этот:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.Resources>
<c:PhotoNameClass x:Key="photoClass" />
<c:BinaryToImageSRCConverter x:Key="imageConverter" />
</Grid.Resources>
<Image Source="{Binding PhotoName, Converter={StaticResource imageConverter}}" DataContext="{StaticResource photoClass}" Width="430" Height="430" VerticalAlignment="Center" Stretch="UniformToFill">
</Image>
</Grid>
</Grid>
Поэтому я добавил атрибут «DataContext» элемента изображения, указывающий имя класса, который переносит мое свойство. В этом сценарии вызывается метод Convert IValueConverter. Однако это неправильно, так как я получаю ошибку в XAML при добавлении DataContext: «Невозможно определить идентификатор приложения вызывающего» и, конечно, при переходе в метод Convert моя строка «value» пуста, поэтому «правильное» «PhotoName» не заполняется.
Спасибо за любые идеи…
PS Вот как я определил свой метод преобразования IValueConverter:
namespace ImageApplication
{
public class BinaryToImageSRCConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{ // <-- Breakpoint here. Never gets triggered except after I added the "DataContext" attribute to the XAML image element.
// but in that case, "value" is an empty string.
if (value != null amp;amp; value is string)
{
...
ИСПРАВЛЕНО ОБНОВЛЕНИЕ
Я устранил эту проблему. Я присвоил имя класса, переносящее мое свойство, свойству DataContext изображения, определенного в коде XAML.
Спасибо вам всем. Я надеюсь, что это кому-нибудь там поможет.
Комментарии:
1. Я в замешательстве. Вы хотите сказать, что точно такой же XAML отлично работает вне списка, но не внутри него?
2. Привет, Гейб, я говорю, что у меня есть другой XAML внутри того же проекта, который использует тот же «синтаксис привязки», что и приведенный выше, и там все работает нормально. Единственное отличие заключается в том, что этот конкретный XAML использует элемент image внутри listbox.
3. предоставьте также код конвертера, если хотите? там может быть что-то, что может помочь
4. Блакомэн: Привет; Я добавил подпись Новообращенного, просто чтобы убедиться, что она правильная. Я не добавлял всю реализацию, потому что я даже не добираюсь до ПЕРВОЙ строки метода Convert, поэтому все остальные детали бессмысленны; мой метод Convert вообще не вызывается, за исключением случаев, когда я добавляю «DataContext» к элементу image. Пожалуйста, следите за тем, чтобы я ОБНОВИЛ ответ на этот вопрос, так как это решение по-прежнему не работает для меня. Спасибо.
Ответ №1:
Он никогда не вызывается, потому что ваше свойство не вызывает PropertyChanged
уведомления. Вам нужно либо сделать его a DependencyProperty
, либо реализовать INotifyPropertyChanged
и вызвать PropertyChanged
событие, когда задано значение свойства.
Комментарии:
1. Привет, Ред. Я реализовал INotifyPropertyChanged, но все равно мой конвертер не вызывается. Я использовал отладчик только для того, чтобы убедиться, что моя реализация верна, и, похоже, она верна, поскольку, когда я присваиваю имени свойства, я могу подтвердить, что происходит вызов «NotifyPropertyChanged» с именем свойства.
2. Эд, я изменил вопрос, чтобы показать мою реализацию предложенных вами решений. Спасибо.
3. @MariusVE: Хорошо. Просто для быстрой проверки работоспособности, посмотрите окно вывода, когда создается ваш элемент управления и когда должно произойти изменение свойства. Вы видите какие-либо ошибки привязки?
4. Ed: я не видел никаких ошибок привязки, появляющихся при изменении свойства. Просто для еще одной проверки работоспособности у меня установлена точка останова в самой первой строке метода Convert, которая представляет собой просто открывающую скобку (т. Е. «{«), Поэтому я уверен, что это не что-то глупое, как отсутствие условия или кто знает что. Я также подтвердил, что путем жесткого кодирования пути к изображению в элементе image внутри xaml изображение отображается так, чтобы оно не было невидимым или что-то в этом роде.
5. Ed: Я отредактировал вопросы, чтобы показать еще одну попытку, которую я предпринял; кажется, что таким образом вызывается мой конвертер… однако моя настройка неверна.