0

I have a flipview containing photo, descbox, detailBtn, hideBtn. I would like if the photo tapped, then descbox and hideBtn appear, while detailBtn not appear. And if the photo tapped again, then descbox and hideBtn not appear, while detailBtn looks. Or if detailBtn clicked, then descbox and hideBtn appear, while detailBtn not appear. And if hideBtn clicked, then descbox and hideBtn not appear, while detailBtn appear.

I'm using the code below:

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;
        }

but an error message like the following: error message

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>

How to handle it?

Note: I tried to use the way in Photo and description on Flipview, but on windows phone 8.1 can not be used

Community
  • 1
  • 1
Rose
  • 613
  • 4
  • 22

1 Answers1

0

You get the error "descbox" and others don't exist in the current context because they are names of UIElements part of a dataTemplate. The dataTemplate would load only during runtime. The target you want to achieve can be achieved with Data Binding and MVVM concepts far less complexly.

I've created a solution for you based on the data you had provided in the question using Data Binding. I've skipped out the MVVM portion as that is vast enough for an answer. So getting started...

The Updated XAML

based on your code project a few things you could change by putting in the DataBinding for the buttons. like below:

<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>

Note: There are UI fails as the margins are not correct but then that's your code. Try not using Margins for an adaptable layout. you could refer my answer here for more details.

The Code Behind for the same:

I've changed the what to do when the Tapped Event is fired. I've left your code commented for reference reasons. The changes in the Code are as below:

    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;
    }

The WaterfallDataItem Class Changes:

I've added the Interface INotifyPropertyChanged and added two new properties IsDataVisible and IsDescriptionVisible which raise the PropertyChanged event incase they are changed.

 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;
    }
}

Please Note: The PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); Only works with C# 6.0 which is available in Visual Studio 2015. For any editions you will have to use

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

as the new Null Condition operator is only available in C# 6.0. For more information on What's new in c# 6.0 please refer this

The Converter:

The Converter is used to convert the true or false value from the properties to visibility

 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();
    }
}

The App.xaml

Finally to make the converter work we need to add the converter to the app.xaml. Modify the Application.Resources like below:

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

Please note all the classes are simply made in the main project no sub folders, So if you place the classes and converters in some different namespace, do remember to update the xmlns: tag on the xaml

Edit: To Make your solution work:

At the bare minimum you could change a few things in your code to make it work, I have made the changes in the answer. The above changes would let you implement the functionality without changing your code very much. Do let me know if there is anything I missed.

Community
  • 1
  • 1
iam.Carrot
  • 4,976
  • 2
  • 24
  • 71
  • Descriptions and photos are from json data binding. This is a sample of his project: https://drive.google.com/file/d/0B4oRSWSS0hKDczRMZzdBLW5JSVk/view?usp=sharing . Note: Flipview on waterfallDetail Page – Rose Nov 23 '16 at 01:52
  • I went through the code. In my opinion, there is a lot happening in that code to achieve very less. I would advise you read the data from the in package json file, deserialize it, and put into an observable collection and follow the code as shown above. you would not need a nivigationHelper or a Observable Directory for it. I'll edit the my answer for the same. – iam.Carrot Nov 23 '16 at 04:53
  • I've tried your code, but still there is some error. Sample project: https://drive.google.com/file/d/0B4oRSWSS0hKDd3FGSmt0REVrY1k/view?usp=sharing How to handle it? And where is boolToInverseVisibilityConverter class? – Rose Nov 23 '16 at 06:52
  • I checked your code. 1. WaterfallDetailsPage.xaml.cs Line 120: it's `var` not `ar`. 2. The Button click event names aren't the same. Please press F12 on the XAML part of the buttonClick event declaration. – iam.Carrot Nov 23 '16 at 06:55
  • but still some error. Project: https://drive.google.com/file/d/0B4oRSWSS0hKDZ0NsZHpWZUxSMEE/view?usp=sharing – Rose Nov 23 '16 at 07:06
  • Could you please tell the error? or attach a screenshot of the error? I went through you link and the test project works perfectly well – iam.Carrot Nov 23 '16 at 07:07
  • here the screenshot for the error: https://drive.google.com/file/d/0B4oRSWSS0hKDLUdvSkEtb2gxOTQ/view?usp=sharing – Rose Nov 23 '16 at 07:11
  • Also If you see the app.xaml you would see the boolToInverseVisibilityConverter is a different key used for the same class (boolToVisibilityConverter) with different property value of `True` for `IsInverseReq` – iam.Carrot Nov 23 '16 at 07:13
  • The errors are not the one's not involving boolToVisibility or InverseVisibility, as those would clear up as soon as you build your solution. Look at errors: 1,2,10,11 in that screenshot you've shared. Fix them and you'll get a working solution. – iam.Carrot Nov 23 '16 at 07:19
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/128782/discussion-between-aditya-sharma-and-rose). – iam.Carrot Nov 23 '16 at 07:29
  • how to fix that? can you share the project? – Rose Nov 23 '16 at 08:00
  • I've added the link in the chat window. You can find the link to the chat window above. – iam.Carrot Nov 23 '16 at 08:13
  • Yes I read it. Please note: For another problem consider writing up a different question along with sample code. For this current question, I am considering this as closed as the issue has been resolved. Kindly mark my answer as the correct one for anyone else facing the same issue. – iam.Carrot Nov 23 '16 at 10:17
  • This has not been resolved because there is an error: https://drive.google.com/file/d/0B4oRSWSS0hKDVkFkSXI5bDRBMFE/view?usp=sharing . The error occurs when I move the codes on my own project. In the project that you send, if WaterfallDataSource class is opened, it will display an error message as well, but the project can be run. While on my project, the project can not be run and the error message appears – Rose Nov 24 '16 at 01:36
  • I've been able to overcome the error by changing the code on //PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); with PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); – Rose Nov 24 '16 at 02:28
  • Yes, I forgot to mention that part. The PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); Only works with C# 6.0 which is available in Visual Studio 2015. For any editions you will have to use your method as the new Null Condition operator is only available in C# 6.0. I've edited my answer for the same – iam.Carrot Nov 24 '16 at 04:37