简体   繁体   中英

Data binding a button visibility in WPF isn't working

Alot of code incoming, Some of this might be useless because i was trying alot of things to get this working.

I am trying to make the button Export Installer invisible unless the selected installer has a value of TRUE on IsDownloaded

so i'll start with my WPF

        DataContext="{Binding Source={StaticResource TheViewModel}}"
    Title="MainWindow" Height="458" Width="755">
<Window.Resources>
    <ViewModel:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
    <ViewModel:InstallerColorConverter x:Key="InstallerColorConverter" />
</Window.Resources>

<ListBox Height="300" Grid.Column="0" Grid.Row="0" SelectionMode="Single" ItemsSource="{Binding SelectedProduct.Installers}" SelectedItem="{Binding SelectedInstaller}" >
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal">
                                    <Ellipse HorizontalAlignment="Right" Fill="{Binding InstallerRelativeToCurrent, Converter={StaticResource InstallerColorConverter}}" Margin="5,5,5,5 " Height="20" Width="20" Stroke="Black"></Ellipse>
                                    <TextBlock Margin="5,0,5,0" Text="{Binding Name}" />
                                    <TextBlock  Text=" " />
                                    <TextBlock Text="{Binding VersionNumber}" />
                                </StackPanel>
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>
                    <StackPanel Grid.Column="0" Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Stretch">
                        <Button Name="btnInstall"  Margin="5,5,5,5" Height="50" Width="75" MouseDoubleClick="btnDownloadInstaller_MouseDoubleClick" >Download</Button>
                        <Button Name="btnExportInstaller" Visibility="{Binding Path=SelectedInstaller.IsDownloaded, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Button}}, Converter={StaticResource BoolToVisibilityConverter}}" Margin="5,5,5,5" Height="50" Width="90" MouseDoubleClick="btnExportInstaller_MouseDoubleClick" >Export Installer</Button>
                    </StackPanel>

The main things to point out in that is

             <Button Name="btnExportInstaller" Visibility="{Binding Path=SelectedInstaller.IsDownloaded, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Button}}, Converter={StaticResource BoolToVisibilityConverter}}" Margin="5,5,5,5" Height="50" Width="90" MouseDoubleClick="btnExportInstaller_MouseDoubleClick" >Export Installer</Button>

and

        <ViewModel:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />

now in my class BoolToVisibilityConver

    public class BoolToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType,
    object parameter, CultureInfo culture)
    {
        var booool = (bool)value;
        if (booool)
            return Visibility.Collapsed;
        else
            return Visibility.Visible;

    }

    public object ConvertBack(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        // Do the conversion from visibility to bool
        return Visibility.Collapsed;
    }
}

Then finally in the view model i have

        private Visibility _IsVisible;
    public Visibility IsVisible
    {
        get { return _IsVisible; }
        set { _IsVisible = value; OnPropertyChanged(nameof(_SelectedInstaller.IsDownloaded)); } 
    }

   private Products _SelectedProduct;
    public Products SelectedProduct
    {
        get { return _SelectedProduct; }
        set { _SelectedProduct = value; OnPropertyChanged(nameof(SelectedProduct)); }

  private Installers _SelectedInstaller;
        public Installers SelectedInstaller
        {
            get { return _SelectedInstaller; }
            set { _SelectedInstaller = value; OnPropertyChanged(nameof(SelectedInstaller)); }

It doesn't work

I'm getting these 2 errors on the console and i don't understand them

System.Windows.Data Error: 1 : Cannot create default converter to perform 'one-way' conversions between types 'System.Boolean' and 'System.Windows.Visibility'. Consider using Converter property of Binding. BindingExpression:Path=SelectedProduct.IsInstalled; DataItem='ViewModel' (HashCode=26987408); target element is 'Grid' (Name=''); target property is 'Visibility' (type 'Visibility')
System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='False' BindingExpression:Path=SelectedProduct.IsInstalled; DataItem='ViewModel' (HashCode=26987408); target element is 'Grid' (Name=''); target property is 'Visibility' (type 'Visibility')

If anyone can point out what i'm doing wrong here i would love you forever!

SOLVED..this is the working code

    <Window.Resources>
    <ViewModel:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />

<Button Name="btnExportInstaller" Visibility="{Binding SelectedInstaller.IsDownloaded , Converter={StaticResource BoolToVisibilityConverter}}" Margin="5,5,5,5" Height="50" Width="90" MouseDoubleClick="btnExportInstaller_MouseDoubleClick">Export Installer</Button>

    public class BoolToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType,
    object parameter, CultureInfo culture)
    {
        var booool = (bool)value;
        if (booool == false)
            return Visibility.Collapsed;
        else
            return Visibility.Visible;

    }

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

Inside viewmodel

        private Installers _SelectedInstaller;
    public Installers SelectedInstaller
    {
        get { return _SelectedInstaller; }
        set { _SelectedInstaller = value; OnPropertyChanged(nameof(SelectedInstaller)); }

        private Visibility _IsVisible;
    public Visibility IsVisible
    {
        get { return _IsVisible; }
        set { _IsVisible = value; OnPropertyChanged(nameof(SelectedInstaller.IsDownloaded)); } 
    }

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