1

I have been searching for this on SO, but I have not found something that is doing exactly what I want. The below attached screenshot is what I want to create, this is done in VBA, but I am trying to create it in C# using WPF. I am importing CSV files with the following structure: "ID","NAME",CheckedINT
e.g.
"1662","BØRSTER",1 <-- 1 = checked, 0 = unchecked.

So when I import a file, it is displaying the information in the listview. However, I cannot manage to create that checkbox for each item/record. I have tried to create it in the XAML file.
If you need some of the code behind, e.g. to load the data into the listview, let me know. I am fairly new to C#, so a thorough explanation would be very much appreciated (using VS15).

Image

XAML:

<Window x:Class="CloneMacro.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:CloneMacro"
        mc:Ignorable="d"
        Title="Clone Macro" Height="350" Width="592.045" Closed="MainWindow_Closed" Icon="C:\Users\Niclas VMWare\Documents\Visual Studio 2015\Projects\CloneMacro\CloneMacro\images\copy.png">
    <Grid Background="#FFDEDEDE" Margin="-1,0,1,0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="71*"/>
            <ColumnDefinition Width="399*"/>
            <ColumnDefinition Width="114*"/>
        </Grid.ColumnDefinitions>
        <Button x:Name="cmdNew" HorizontalAlignment="Left" Margin="39,36,0,0" VerticalAlignment="Top" Width="39" Height="40" ToolTip="New" Grid.ColumnSpan="2" Click="cmdNew_Click">
            <Image x:Name="imgNew" HorizontalAlignment="Left" Height="37" VerticalAlignment="Top" Width="36" Source="C:\Users\Niclas VMWare\Documents\Visual Studio 2015\Projects\CloneMacro\CloneMacro\images\Generic_Document.png" RenderTransformOrigin="0.172,1.089"/>
        </Button>
        <Button x:Name="cmdOpen" HorizontalAlignment="Left" Margin="8,36,0,0" VerticalAlignment="Top" Width="39" Height="40" ToolTip="Open" Grid.Column="1" Click="cmdOpen_Click">
            <Image x:Name="imgOpen" HorizontalAlignment="Left" Height="37" VerticalAlignment="Top" Width="36" Source="C:\Users\Niclas VMWare\Documents\Visual Studio 2015\Projects\CloneMacro\CloneMacro\images\folder_Open_32xLG.png"/>
        </Button>
        <Button x:Name="cmdSave" HorizontalAlignment="Left" Margin="48,36,0,0" VerticalAlignment="Top" Width="39" Height="40" ToolTip="Save" Grid.Column="1" Click="cmdSave_Click">
            <Image x:Name="imgSave" HorizontalAlignment="Left" Height="37" VerticalAlignment="Top" Width="36" Source="C:\Users\Niclas VMWare\Documents\Visual Studio 2015\Projects\CloneMacro\CloneMacro\images\save_16xLG.png"/>
        </Button>
        <Button x:Name="cmdDelete" HorizontalAlignment="Left" Margin="139,36,0,0" VerticalAlignment="Top" Width="39" Height="40" Grid.Column="1" Click="cmdDelete_Click">
            <Image x:Name="imgDelete" HorizontalAlignment="Left" Height="33" VerticalAlignment="Top" Width="32" Source="C:\Users\Niclas VMWare\Documents\Visual Studio 2015\Projects\CloneMacro\CloneMacro\images\action_Cancel_16xLG.png" ToolTip="Delete" RenderTransformOrigin="1.334,0.534"/>
        </Button>
        <Button x:Name="cmdNewStore" HorizontalAlignment="Left" Margin="179,36,0,0" VerticalAlignment="Top" Width="39" Height="40" Grid.Column="1" Click="cmdNewStore_Click">
            <Image x:Name="imgNewStore" HorizontalAlignment="Left" Height="37" VerticalAlignment="Top" Width="36" Source="C:\Users\Niclas VMWare\Documents\Visual Studio 2015\Projects\CloneMacro\CloneMacro\images\action_add_16xLG.png" ToolTip="Add New Store" RenderTransformOrigin="0.5,0.5"/>
        </Button>
        <Button x:Name="cmdExecute" HorizontalAlignment="Left" Margin="259,36,0,0" VerticalAlignment="Top" Width="39" Height="40" ToolTip="Execute" Grid.Column="1" Click="cmdExecute_Click">
            <Image x:Name="image" HorizontalAlignment="Left" Height="37" VerticalAlignment="Top" Width="37" Source="C:\Users\Niclas VMWare\Documents\Visual Studio 2015\Projects\CloneMacro\CloneMacro\images\StatusAnnotations_Play_32xLG_color.png"/>
        </Button>
        <Button x:Name="cmdCancel" HorizontalAlignment="Left" Margin="299,36,0,0" VerticalAlignment="Top" Width="39" Height="40" ToolTip="Cancel" Grid.Column="1" Click="cmdCancel_Click">
            <Image x:Name="imgCancel" HorizontalAlignment="Left" Height="37" VerticalAlignment="Top" Width="36" Source="C:\Users\Niclas VMWare\Documents\Visual Studio 2015\Projects\CloneMacro\CloneMacro\images\CancelApproval_32x32.png"/>
        </Button>
        <CheckBox x:Name="chOpenLastUsed" Content="Open Last Used File" Margin="360,48,0,0" VerticalAlignment="Top" Height="21" Width="147" HorizontalAlignment="Left" Grid.Column="1" Grid.ColumnSpan="2"/>
        <ListView x:Name="lvStores" HorizontalAlignment="Left" Height="161" Margin="39,98,0,0" VerticalAlignment="Top" Width="370" Grid.ColumnSpan="2">
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                       <GridViewColumn Header="ID" Width="50">
                          <GridViewColumn.CellTemplate>
                              <DataTemplate>
                                <CheckBox Content="{Binding sID}" IsChecked="{Binding IsChecked}"/>
                              </DataTemplate>
                            </GridViewColumn.CellTemplate>
                          </GridViewColumn>
                        <GridViewColumn Header="Name" Width="Auto" DisplayMemberBinding="{Binding Path=sName}"/>
                        <GridViewColumn Header="Import File" Width="Auto" DisplayMemberBinding="{Binding Path=sImportFile}"/>
                    </GridView.Columns>
                </GridView>
            </ListView.View>
        </ListView>
        <Label x:Name="lblProgress" x:FieldModifier="public" Content="Status Text" HorizontalAlignment="Left" Margin="40,264,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2" Width="369" BorderThickness="1" BorderBrush="#FF7C7C7C"/>
        <Button x:Name="ComDialog" Grid.Column="1" HorizontalAlignment="Left" Margin="359,119,0,0" VerticalAlignment="Top" Width="48" Height="51" Grid.ColumnSpan="2">
            <Image x:Name="imgComDialog" HorizontalAlignment="Left" Height="44" VerticalAlignment="Top" Width="48" Source="C:\Users\Niclas VMWare\Documents\Visual Studio 2015\Projects\CloneMacro\CloneMacro\images\DialogID_6220_32x.png"/>
        </Button>
    </Grid>
</Window> 

.CS

    public MainWindow()
    {
        // Leave this to show the UI
        InitializeComponent();

        lblProgress.Content = "";

        lvStores.ItemsSource = ReadCSV(@"C:\Users\Niclas VMWare\Downloads\TEST FILE.pcf");

        //SetButtonState();

        string sFile;
    }

    public class Store
    {
        public string sName { get; set; }
        public string sImportFile { get; set; }
        public string sID { get; set; }
        public bool IsChecked { get; set; }

        public Store(string id, string strName, string isChecked, string strImportFile)
        {
            sName = strName.Replace("\"","");
            sImportFile = strImportFile;
            sID = id.Replace("\"","");

            int iBool = Convert.ToInt32(isChecked);

            switch (iBool)
            {
                case 0: IsChecked = false; break;
                case 1: IsChecked = true; break;
                default: throw new InvalidOperationException("Third value in PCF file must be 0 or 1!");
            }
        }
    }

    public IEnumerable<Store> ReadCSV(string fileName)
    {
        // Check file extension
        string[] lines = File.ReadAllLines(Path.ChangeExtension(fileName, ".pcf"), Encoding.GetEncoding(65001));

        // lines.Select allows to project each line as a Store. 
        // This will give IEnumerable<Store> back.
        return lines.Select(line =>
        {
            string[] data = line.Split(',');
            // Return store data with the data in order.
            return new Store(data[0], data[1], data[2], fileName);
        });
    }
3
  • Do you have any code for populating the ListView? Commented Aug 1, 2017 at 20:19
  • @MattL. I updated the code, hope it is enough? Commented Aug 1, 2017 at 20:28
  • Updated XAML and .CS with working code in case people stumble over this in the future. Commented Aug 2, 2017 at 8:05

2 Answers 2

2

Modify your listview's first column definition to be

                    <GridViewColumn Header="ID" Width="50">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox Content="{Binding sID}" />
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>

I believe it will address your problem. Databinding may get affected and you'll need more XAML/code to handle that.

What I have done here is take the default definition of a GridViewColumn data template and replaced it with my own. You can read more about it in the Data templating topic.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for your answer. I just tried and it is indeed adding checkboxes as I want. However, it is now displaying the 0/1 next to the checkbox in the ID column. Then the actual ID e.g. "1662" is displayed in the Name column, and "Børster" is shown in the Import File column. Is this due to the databinding? I have updated my code with the dataview load.
In a manner. But then, you are passing that 0/1 to sID in your code. It should be return new Store(data[1], string.Empty, Convert.ToInt32(data[0]));
I cannot get it to work. I am getting a DateTime exception. I guess what I need to do, is to use the 0/1 to fill out the checkboxes and then display the ID in the column.
You could use a Converter that accepts the sID and returns True for 1 and False for 0. Something like <CheckBox IsChecked="{Binding sID, Converter={StaticResource yourConverterName}}" Here is some reference wpf-tutorial.com/data-binding/…
Updated my code. Changed the datatype to string. So now I am getting the ID in the ID column. Can I use IsChecked?
|
1

Teach me wrong, but your csv file contains the columns ID, Name, IsChecked and you will parse it to new Store(id: data[0], strName: data[1], strImportFile: data[2]).

So following your example the properties of your new Store object will have the following values:

public class Store
{
    public string sName { get; set; }         // BØRSTER
    public string sImportFile { get; set; }   // 1 
    public string sID { get; set; }           // 1662

    public Store(string id, string strName, string strImportFile)
    {
        sName = strName;
        sImportFile = strImportFile;
        sID = id;
    }
}

You should add another property to your class and another parameter to your constructor:

public bool IsChecked { get; set; }

public Store(string id, string strName, string isChecked, string strImportFile)
{
    sID = id;
    sName = strName;

    IsChecked = isChecked == "1";

    sImportFile = strImportFile;
}

So now you can create the new Store instance by calling
new Store(data[0], data[1], data[2], fileName).

The binding should now look like
<CheckBox IsChecked="{Binding IsChecked}" Content="{Binding sID}" />


At least let me give you a kind advice. You may take a look at the Microsoft Naming Guidelines. For example: Properties should be named in PascalCasing and you also should avoid Hungarian notation like strName. But this is just my personal opinion.

5 Comments

Thanks for your solution. It makes sense to me, however, I do not understand why you have fileName in the new Store instance.
@Niclas I assumed that you want to hold the file name from string[] lines = File.ReadAllLines(Path.ChangeExtension(fileName, ".pcf"), Encoding.GetEncoding(65001)); with the property sImportFile and bind the sImportFile to the column Import File
You are correct, I just noticed now. However, I cannot get your code to work. I managed to fix it now, so thank you for guiding me!! Will update my OP with the answer.
The simple boolean conversion did not work, so I had to do it with a switch case. Thanks once again.
@Niclas Your right. The simple cast did not work. I will adjust my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.