flipview на Windows Phone 8.1 ошибка Имя '' не существует в текущем контексте

У меня есть флип-просмотр, содержащий фото, descbox, detailBtn, hideBtn. Я бы хотел, чтобы при нажатии на фото появлялись descbox и hideBtn, а detailBtn не появлялись. А если фото тапнуть еще раз, то descbox и hideBtn не появляются, а detailBtn смотрит. Или, если нажата detailBtn, то появляются descbox и hideBtn, а detailBtn не появляется. А если нажимается hideBtn, то descbox и hideBtn не появляются, а detailBtn появляется.

Я использую код ниже:

private async void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)
        {                
            var item = await NatureDataSource.GetItemAsync((String)e.NavigationParameter);
        var group = await NatureDataSource.GetGroupByItemAsync(item);
        this.DefaultViewModel["Group"] = group;
        this.DefaultViewModel["Item"] = item;
        }

 public bool _IsOn;
        public bool IsOn
        {
            get
            {
                return _IsOn;
            }
            set
            {
                _IsOn = value;
            }
        }

        private void photo_Tapped(object sender, TappedRoutedEventArgs e)
        {
            IsOn = !IsOn;
            if (!IsOn)
            {
                descbox.Visibility = Visibility.Collapsed;
                detailBtn.Visibility = Visibility.Visible;
                hideBtn.Visibility = Visibility.Collapsed;
            }
            else
            {
                descbox.Visibility = Visibility.Visible;
                detailBtn.Visibility = Visibility.Collapsed;
                hideBtn.Visibility = Visibility.Visible;
            }
        }

private void detailBtn_Tapped(object sender, TappedRoutedEventArgs e)
        {
            descbox.Visibility = Visibility.Visible;
            detailBtn.Visibility = Visibility.Collapsed;
            hideBtn.Visibility = Visibility.Visible;
        }

но сообщение об ошибке, подобное следующему: сообщение об ошибке

XAML:

<FlipView x:Name="narrowFlipview" Grid.Row="1" ItemsSource="{Binding Group.Items}" SelectedItem="{Binding Item, Mode=TwoWay}" Foreground="{x:Null}">
            <FlipView.ItemTemplate>
                <DataTemplate>
                    <Grid x:Name="ContentRoot">
                        <Grid.ChildrenTransitions>
                            <TransitionCollection>
                                <EdgeUIThemeTransition Edge="Left"/>
                            </TransitionCollection>
                        </Grid.ChildrenTransitions>
                        <ScrollViewer x:Name="myScroll" VerticalScrollBarVisibility="Auto" Margin="0,0,0,0" VerticalScrollMode="Auto" HorizontalScrollBarVisibility="Auto" ZoomMode="Enabled" MinZoomFactor="1" HorizontalScrollMode="Auto">
                            <StackPanel Height="325" Width="558">
                                <Image x:Name="photo" Source="{Binding ImagePath}" Stretch="Uniform" Height="320" Tapped="photo_Tapped" Margin="0,0,0.333,0" />
                                <Border x:Name="descbox" Background="#A52C2C2C" Height="120" VerticalAlignment="Bottom" Visibility="Collapsed" Margin="0,-120,0,0">
                                    <ScrollViewer VerticalScrollMode="Auto" Height="auto" HorizontalScrollBarVisibility="Visible">
                                        <StackPanel Width="538">
                                            <TextBlock x:Name="desc" Text="{Binding Description}" FontFamily="verdana" FontSize="17" Foreground="#CCFFFFFF" TextWrapping="Wrap" Padding="0,10" TextAlignment="Justify" Height="auto"/>
                                        </StackPanel>
                                    </ScrollViewer>
                                </Border>
                                <Image x:Name="detailBtn" Source="images/media/arrow_up.png" Margin="0,-40,0,0" Height="40" Width="40" HorizontalAlignment="Right" Tapped="detailBtn_Tapped"/>
                                <Image x:Name="hideBtn" Source="images/media/arrow_down.png" Margin="0,-285,0,0" Height="40" Width="40" HorizontalAlignment="Right" Visibility="Collapsed" Tapped="hideBtn_Tapped"/>
                            </StackPanel>
                        </ScrollViewer>
                    </Grid>
                </DataTemplate>
            </FlipView.ItemTemplate>
        </FlipView>

Как с этим справиться?

Примечание. Я пытался использовать способ в Фото и описание на Flipview , но на windows phone 8.1 нельзя использовать


person Rose    schedule 22.11.2016    source источник


Ответы (1)


Вы получаете ошибку «descbox», а другие не существуют в текущем контексте, потому что они являются именами UIElements, частью dataTemplate. DataTemplate будет загружаться только во время выполнения. Цель, которую вы хотите достичь, может быть достигнута с помощью концепций привязки данных и MVVM гораздо проще.

Я создал для вас решение на основе данных, которые вы предоставили в вопросе, используя привязку данных. Я пропустил часть MVVM, так как она достаточно обширна для ответа. Итак, приступаем...

Обновленный XAML

на основе вашего проекта кода несколько вещей, которые вы могли бы изменить, вставив DataBinding для кнопок. как показано ниже:

<FlipView x:Name="narrowFlipview" Grid.Row="1" ItemsSource="{Binding Group.Items}" SelectedItem="{Binding Item, Mode=TwoWay}"  Foreground="{x:Null}">
        <FlipView.ItemTemplate>
            <DataTemplate>
                <Grid x:Name="ContentRoot">
                    <Grid.ChildrenTransitions>
                        <TransitionCollection>
                            <EdgeUIThemeTransition Edge="Left"/>
                        </TransitionCollection>
                    </Grid.ChildrenTransitions>
                    <ScrollViewer x:Name="myScroll" VerticalScrollBarVisibility="Auto" Margin="0,0,0,0" VerticalScrollMode="Auto" HorizontalScrollBarVisibility="Auto" ZoomMode="Enabled" MinZoomFactor="1" HorizontalScrollMode="Auto">
                        <StackPanel Height="325" Width="558">
                            <Image x:Name="photo" Source="{Binding ImagePath}" Stretch="Uniform" Height="320" Tapped="photo_Tapped" Margin="0,0,0.333,0" />
                            <Border x:Name="descbox" Background="#A52C2C2C" Height="120" VerticalAlignment="Bottom" Visibility="{Binding IsDescriptionVisible,Converter={StaticResource boolToVisibilityConverter}}" Margin="0,-120,0,0">
                                <ScrollViewer VerticalScrollMode="Auto" Height="auto" HorizontalScrollBarVisibility="Visible">
                                    <StackPanel Width="538">
                                        <TextBlock x:Name="desc" Text="{Binding Description}"  FontFamily="verdana" FontSize="17" Foreground="#CCFFFFFF" TextWrapping="Wrap" Padding="0,10" TextAlignment="Justify" Height="auto"/>
                                    </StackPanel>
                                </ScrollViewer>
                            </Border>
                            <AppBarButton x:Name="detailBtn" Icon="Upload" Margin="0,-40,0,0" Height="40" Width="40" HorizontalAlignment="Right" Visibility="{Binding IsDescriptionVisible,Converter={StaticResource boolToInverseVisibilityConverter}}" Click="DetailsBtn_Click"/>
                            <AppBarButton x:Name="hideBtn" Icon="Download"  Margin="0,-285,0,0" Height="40" Width="40" HorizontalAlignment="Right" Visibility="{Binding IsDescriptionVisible,Converter={StaticResource boolToVisibilityConverter}}" Click="HideBtn_Click"/>
                        </StackPanel>
                    </ScrollViewer>
                </Grid>
            </DataTemplate>
        </FlipView.ItemTemplate>
    </FlipView>

Примечание. Возможны сбои пользовательского интерфейса, поскольку поля неверны, но тогда это ваш код. Попробуйте не использовать Margins для адаптивного макета. вы можете сослаться на мой ответ здесь для получения более подробной информации.

Код для того же:

Я изменил действия при запуске события Tapped. Я оставил ваш код комментарием для справки. Изменения в Кодексе следующие:

    private void photo_Tapped(object sender, TappedRoutedEventArgs e)
    {
        var currentItem = narrowFlipview.SelectedItem as WaterfallDataItem;
        currentItem.IsDataVisible = !currentItem.IsDataVisible;
        //IsOn = !IsOn;
        //if (!IsOn)
        //{
        //    descbox.Visibility = Visibility.Collapsed;
        //    detailBtn.Visibility = Visibility.Visible;
        //    hideBtn.Visibility = Visibility.Collapsed;
        //}
        //else
        //{
        //    descbox.Visibility = Visibility.Visible;
        //    detailBtn.Visibility = Visibility.Collapsed;
        //    hideBtn.Visibility = Visibility.Visible;
        //}
    }



    private void DetailsBtn_Click(object sender, RoutedEventArgs e)
    {
        var currentItem = narrowFlipview.SelectedItem as WaterfallDataItem;
        currentItem.IsDescriptionVisible = true;
    }

    private void HideBtn_Click(object sender, RoutedEventArgs e)
    {
        var currentItem = narrowFlipview.SelectedItem as WaterfallDataItem;
        currentItem.IsDescriptionVisible = false;
    }

Изменения класса WaterfallDataItem:

Я добавил интерфейс INotifyPropertyChanged и добавил два новых свойства IsDataVisible и IsDescriptionVisible, которые вызывают событие PropertyChanged в случае их изменения.

 public class WaterfallDataItem:INotifyPropertyChanged
{
    public WaterfallDataItem(String uniqueId, String title, String imagePath, String description, String content)
    {
        this.UniqueId = uniqueId;
        this.Title = title;
        this.Description = description;
        this.ImagePath = imagePath;
        this.Content = content;
    }

    public string UniqueId { get; private set; }
    public string Title { get; private set; }
    public string Description { get; private set; }
    public string ImagePath { get; private set; }
    public string Content { get; private set; }

    //for the image tap to show description functionality
    private bool isDataVisible;
    public bool IsDataVisible
    {
        get { return isDataVisible; }
        set
        {
            isDataVisible = value;
            if (value)
                IsDescriptionVisible = true;
            RaisePropertyChanged("IsDataVisible");
        }
    }

    //for hide and show the details pannel and hide and show content based on that
    private bool isDescriptionVisible;
    public bool IsDescriptionVisible
    {
        get { return isDescriptionVisible; }
        set { isDescriptionVisible = value; RaisePropertyChanged("IsDescriptionVisible"); }
    }

    //raises the event to the view if any of these properties change
    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public override string ToString()
    {
        return this.Title;
    }
}

Обратите внимание: PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); работает только с C# 6.0, который доступен в Visual Studio 2015. Для любых выпусков вам придется использовать

if (PropertyChanged != null)
{
    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

поскольку новый оператор Null Condition доступен только в C# 6.0. Для получения дополнительной информации о том, что нового в c# 6.0, см. эту

Преобразователь:

Преобразователь используется для преобразования истинного или ложного значения из свойств в видимость.

 public class boolToVisibilityConverter : IValueConverter
{
    public bool isInverseReq { get; set; }
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        bool val = (bool)value;
        if(isInverseReq)
        {
            if (val)
                return Visibility.Collapsed;
            else
                return Visibility.Visible;
        }
        else
        {
            if (val)
                return Visibility.Visible;
            else
                return Visibility.Collapsed;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

App.xaml

Наконец, чтобы конвертер заработал, нам нужно добавить конвертер в app.xaml. Измените Application.Resources, как показано ниже:

<Application.Resources>
    <local:boolToVisibilityConverter x:Key="boolToVisibilityConverter" isInverseReq="False"/>
    <local:boolToVisibilityConverter x:Key="boolToInverseVisibilityConverter" isInverseReq="True"/>
</Application.Resources>

Обратите внимание, что все классы просто создаются в основном проекте без подпапок. Поэтому, если вы помещаете классы и преобразователи в какое-то другое пространство имен, не забудьте обновить тег xmlns: в xaml.

Изменить: чтобы ваше решение работало:

Как минимум, вы можете изменить несколько вещей в своем коде, чтобы он работал, я внес изменения в ответ. Вышеупомянутые изменения позволят вам реализовать функциональность, не сильно меняя код. Дайте мне знать, если я что-то пропустил.

person iam.Carrot    schedule 22.11.2016
comment
Описания и фотографии взяты из привязки данных json. Это пример его проекта: drive.google.com/file/ d/0B4oRSWSS0hKDczRMZzdBLW5JSVk/ . Примечание. Flipview на странице подробностей водопада. - person Rose; 23.11.2016
comment
Я прошел код. На мой взгляд, в этом коде многое делается для того, чтобы добиться меньшего. Я бы посоветовал вам прочитать данные из json-файла в пакете, десериализовать их, поместить в наблюдаемую коллекцию и следовать коду, как показано выше. вам не понадобится nivigationHelper или Observable Directory. Я отредактирую свой ответ на то же самое. - person iam.Carrot; 23.11.2016
comment
Я пробовал ваш код, но все равно есть какая-то ошибка. Пример проекта: drive.google.com/file/d/0B4oRSWSS0hKDd3FGSmt0REVrY1k/ Как с этим справиться? А где класс boolToInverseVisibilityConverter? - person Rose; 23.11.2016
comment
Я проверил ваш код. 1. WaterfallDetailsPage.xaml.cs Строка 120: это var, а не ar. 2. Имена событий нажатия кнопки не совпадают. Нажмите F12 в части XAML объявления события buttonClick. - person iam.Carrot; 23.11.2016
comment
но все же какая-то ошибка. Проект: drive.google.com/file/d/0B4oRSWSS0hKDZ0NsZHpWZUxSMEE/ - person Rose; 23.11.2016
comment
Не могли бы вы сказать ошибку? или приложить скриншот ошибки? Я прошел по вашей ссылке, и тестовый проект работает отлично - person iam.Carrot; 23.11.2016
comment
Также, если вы видите app.xaml, вы увидите, что boolToInverseVisibilityConverter — это другой ключ, используемый для того же класса (boolToVisibilityConverter) с другим значением свойства True для IsInverseReq - person iam.Carrot; 23.11.2016
comment
Ошибки не связаны с boolToVisibility или InverseVisibility, поскольку они прояснятся, как только вы создадите свое решение. Посмотрите на ошибки: 1,2,10,11 на скриншоте, которым вы поделились. Исправьте их, и вы получите рабочее решение. - person iam.Carrot; 23.11.2016
comment
Давайте продолжим это обсуждение в чате. - person iam.Carrot; 23.11.2016
comment
как это исправить? можешь поделиться проектом? - person Rose; 23.11.2016
comment
Я добавил ссылку в окно чата. Вы можете найти ссылку на окно чата выше. - person iam.Carrot; 23.11.2016
comment
Да я читал. Обратите внимание: для другой проблемы рассмотрите возможность написания другого вопроса вместе с образцом кода. Что касается этого текущего вопроса, я считаю его закрытым, поскольку проблема была решена. Пожалуйста, отметьте мой ответ как правильный для всех, кто сталкивается с той же проблемой. - person iam.Carrot; 23.11.2016
comment
Проблема не решена из-за ошибки: drive.google.com. /file/d/0B4oRSWSS0hKDVkFkSXI5bDRBMFE/ . Ошибка возникает, когда я перемещаю коды в свой собственный проект. В проекте, который вы отправляете, если класс WaterfallDataSource открыт, он также отобразит сообщение об ошибке, но проект можно будет запустить. В моем проекте проект не может быть запущен, и появляется сообщение об ошибке - person Rose; 24.11.2016
comment
Мне удалось устранить ошибку, изменив код //PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); с обработчиком PropertyChangedEventHandler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); - person Rose; 24.11.2016
comment
Да, я забыл упомянуть эту часть. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); Работает только с C# 6.0, который доступен в Visual Studio 2015. Для любых выпусков вам придется использовать свой метод, поскольку новый оператор Null Condition доступен только в C# 6.0. Я отредактировал свой ответ для того же - person iam.Carrot; 24.11.2016