简体   繁体   中英

bool to System.Windows.Visibility (binding issues when dynamically creating DataGridColumnHeaders)

I am caught up in a scenario where I have to dynamically create datagrid columns and must create the columns in C# code. I have a checkbox in a separate area of code for each generated column. The checkbox determines whether or not the specific column is hidden or visible. The checkbox is bound to the GameAttributes.Visible property. However, the DataGrid Visibility property is of a different type. I tried using the BooleanToVisibilityConverter, but still receive a compile error (as I figured). Does any have any efficient workarounds to this problem?

The error I am encountering:

Cannot implicitly convert type 'bool' to 'System.Windows.Visibility'    

EDIT: Compiler error has been resolved, however the binding does not appear to work for visibility.

XAML:

<DataGrid ItemsSource="{Binding}" 
              DockPanel.Dock="Top" 
              AutoGenerateColumns="False" 
              HorizontalAlignment="Stretch" 
              Name="GameDataGrid" 
              VerticalAlignment="Stretch" 
              CanUserAddRows="False" 
              CanUserDeleteRows="False" 
              CanUserResizeRows="False"
              IsReadOnly="True"
              >

View:

GameAttributes.Add(new GameInfoAttributeViewModel() { Visible = true, Description = "Name", BindingName = "Name" });
GameAttributes.Add(new GameInfoAttributeViewModel() { Visible = false, Description = "Description", BindingName = "Description" });
GameAttributes.Add(new GameInfoAttributeViewModel() { Visible = false, Description = "Game Exists", BindingName = "GameExists" });
foreach (GameInfoAttributeViewModel attribute in GameAttributes)
{

    DataGridTextColumn column = new DataGridTextColumn
    {
        Header = attribute.Description,
        Binding = new Binding(attribute.BindingName),
    };

    Binding visibilityBinding = new Binding();
    visibilityBinding.Path = new PropertyPath("Visible");
    visibilityBinding.Source = attribute;
    visibilityBinding.Converter = new BooleanToVisibilityConverter();
    BindingOperations.SetBinding(column, VisibilityProperty, visibilityBinding);

    GameDataGrid.Columns.Add(column);

}

ViewModel:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;

namespace DonsHyperspinListGenerator
{
    class GameInfoAttribute
    {
        public string Description { get; set; }
        public bool Visible { get; set; }
        public string BindingName { get; set; }
    }

    //todo: move to separate class
    class GameInfoAttributeViewModel : INotifyPropertyChanged
    {
        private GameInfoAttribute mGameInfo = new GameInfoAttribute();

        public string Description
        {
            get { return mGameInfo.Description; }
            set
            {
                if (mGameInfo.Description != value)
                {
                    mGameInfo.Description = value;
                    InvokePropertyChanged("Description");
                }
            }
        }

        public bool Visible
        {
            get { return mGameInfo.Visible; }
            set
            {
                if (mGameInfo.Visible != value)
                {
                    mGameInfo.Visible = value;
                    InvokePropertyChanged("Visible");
                }
            }
        }

        public string BindingName
        {
            get { return mGameInfo.BindingName; }
            set
            {
                if (mGameInfo.BindingName != value)
                {
                    mGameInfo.BindingName = value;
                    InvokePropertyChanged("BindingName");
                }
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        private void InvokePropertyChanged(string propertyName)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            PropertyChangedEventHandler changed = PropertyChanged;
            if (changed != null) changed(this, e);
        }
    }
}

Doesn't have anything to do with your binding or your value converter. You're making this assignment:

Visibility = attribute.Visible

where you create a new column in the View.

That's your compile error. Visibility is a System.Windows.Visibility, and attribute.Visible is a bool. You can't set Visibility to a bool. If this value is being set via a Binding anyway, then you really don't need to be setting it manually (indeed it will clear your Binding).

Edit:

Here's an example of how to set the binding in the code behind to use the value converter:

var binding = new Binding();
binding.Source = attribute;
binding.Path = new PropertyPath("Visible");
binding.Converter = (BooleanToVisibilityConverter)Resources["BoolToVisibilityConverter"];

BindingOperations.SetBinding(column, DataGridTemplateColumn.VisibilityProperty, binding);

Second Edit: I see a couple of things in the above code that may be a problem:

Firstly, when you're setting your binding, it looks like you're setting the binding on just " VisibilityProperty " for your DependencyProperty. I'm not sure what that is in the context of your view (probably UserControl.VisibilityProperty , or something). The specific DependencyProperty that you want to set is on the DataGridTemplateColumn type, so I believe you'll want to set it to DataGridTemplateColumn.VisibilityProperty instead.

So this line: BindingOperations.SetBinding(column, VisibilityProperty, visibilityBinding);

becomes this: BindingOperations.SetBinding(column, DataGridTemplateColumn.VisibilityProperty, visibilityBinding);

Another thing is this line in your object initializer for the DataGridTextColumn:

Binding = new Binding(attribute.BindingName),

I'm not sure what you're doing with that line, but it could possibly be causing an issue with the overall DataContext of the column (which may in turn cause a problem for the Visibility binding). I'm not positive that it's an issue, but it's definitely not needed for setting the Visibility Binding. I had the code that I provided in my answer working in an example project, and all I added where the lines I provided above (after taking out the assignment in the column initializer that had caused the compile error.

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