简体   繁体   中英

WPF Binding not updating Visibility

I'm having trouble with the binding to a visibility of a grid. I've had projects where I've done this before and have tried to replicate the same coding used previously, and I've searched around and added in the bool to visibility converter based off some other articles but still nothing.

All that I am trying to do so far in this project is have a set of options that will be provided to the user. When they select one option it will either bring up sub-options or just take them to the proper area. I have the binding set to a bool object and have at times created little message boxes and others just to let me know if the program is reaching everywhere. I get every messagebox along the way, so it appears to be reaching every piece of code.

Can anyone shed some light on what I am doing wrong or point me in the correct direction?

Converter in Windows.Resources (Edited to show all code in Windows.Resources)

<Window.Resources>
    <Style TargetType="{x:Type Button}">
        <Setter Property="FontSize" Value="15"/>
        <Setter Property="FontWeight" Value="Bold" />
        <Setter Property="Height" Value="50" />
        <Setter Property="Width" Value="100" />
        <Setter Property="Margin" Value="0,0,0,0" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="VerticalAlignment" Value="Center" />
    </Style>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>

Code in the rest of the window

<Grid>
    <Grid x:Name="grid_mainMenu" Visibility="{Binding MainMenuVisibility, Converter={StaticResource BooleanToVisibilityConverter}}" Margin="0,0,0,20">
        <Grid.RowDefinitions>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>
        <Button x:Name="button_Items" Content="Items" Grid.Row="0" Click="button_Items_Click"/>
        <Button x:Name="button_Orders" Content="Orders" Grid.Row="1" Click="button_Orders_Click" />
        <TextBox Text="{Binding StatusMessage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="0,0,0,0" HorizontalAlignment="Left"  VerticalAlignment="Top" Height="100" Width="100"/>
    </Grid>
    <Grid x:Name="grid_itemMenu" Visibility="{Binding ItemMenuVisibility, Converter={StaticResource BooleanToVisibilityConverter}}" Margin="0,0,0,20">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>
        <Label Content="Item Menu" Grid.Row="0" FontSize="20" FontWeight="Bold" Margin="0,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        <Button Grid.Row="1" x:Name="button_itemMaintenance" Content="Maintenance"/>
        <Button Grid.Row="2" x:Name="button_itemCreation" Content="Create"/>
    </Grid>
    <DockPanel Height="25" Margin="0,0,0,0" VerticalAlignment="Bottom">
        <StatusBar DockPanel.Dock="Bottom">
            <StatusBarItem>
                <TextBlock Text="{Binding StatusMessage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
            </StatusBarItem>
        </StatusBar>
    </DockPanel>
</Grid>

Here is the code in the class

    public bool MainMenuVisibility
    {
        get { return _mainMenuVisibility; }
        set { _mainMenuVisibility = value; RaisePropertyChanged(); }
    }

    public bool ItemMenuVisibility
    {
        get { return _itemMenuVisibility; }
        set
        { _itemMenuVisibility = value; RaisePropertyChanged(); }
    }

    public bool OrderMenuVisibility
    {
        get { return _orderMenuVisibility; }
        set { _orderMenuVisibility = value;  RaisePropertyChanged(); }
    }

Main Constructor

public Menu_View()
    {
        ShowMainMenu();
    }

A couple of the controls

public void ShowMainMenu()
    {
        MainMenuVisibility = true;
        HideItemMenu();
        HideOrderMenu();
        StatusMessage = "Showing main menu";
    }

    public void HideMainMenu()
    {
        MainMenuVisibility = false;
        StatusMessage = "Hid main menu";
    }

    public void ShowItemMenu()
    {
        try
        {
            //Reaches, but never updates
            ItemMenuVisibility = true;
            HideMainMenu();
            HideOrderMenu();
        }
        catch(Exception error)
        {
            //Never shows anything here
            StatusMessage = "Failed to load item menu";
        }
        finally
        {
            //Does not update, but reaches here
            StatusMessage = "Showing item menu";
        }
    }

Program starts by showing the main menu, when user clicks a button for Items it is supposed to show the item menu. The button click calls ShowItemMenu(). I have verified that that does happen and is called in proper order.

I have verified that ShowItemMenu() does work but putting in the constructor instead of ShowMainMenu(). Either one works fine, but neither will cause an update after the initial loading even though they are reached after button presses.

Sorry if I did not include everything I needed.

EDIT:

I believe that I actually had two issues going on simultaneously. One an improperly configured data converter. Answer and reference below.

As well as an issue in my window code here:

public MainWindow()
    {
        InitializeComponent();
        menuView = new Menu_View();
        this.DataContext = new Menu_View();
    }

    Menu_View menuView;

I believe this was part of the issue. I was creating a menuView of type Menu_View. On initialize I assigned menuView to a new Menu_View() and then assigned my DataContext to a new Menu_View() instead of menuView. All commands were updating menuView and I was updating the one assigned to the DataContext.

Add this converter class to your project.

 class BooleanToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is Boolean && (bool)value)
        {
            return Visibility.Visible;
        }
        return Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is Visibility && (Visibility)value == Visibility.Visible)
        {
            return true;
        }
        return false;
    }
}

Referance

You could go without the Boolean converter if you choose. You won't have to write any code-behind.

<Grid>
    <Grid.Style>
        <Style TargetType="{x:Type Grid}">
            <Setter Property="Visibility" Value="Collapsed" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=MyBoolValue}" Value="True">
                    <Setter Property="Visibility" Value="Visible" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Grid.Style>
</Grid>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM