How to retrieve data from csv file and put in respective textboxes - c#

I have used 3 textboxes to extract filename, file extension and path from a particular folder respectively in textbox2, textbox3 & textbox1. This data get stored in a .csv file.
Problem 1: I want to extract this data in their respective textbox from reading this .csv file, when I press button6.
Problem 2: how can I show the relative path rather than showing full path? (I think substring method be used for this problem but how :|)
For example:
Showing Chrome\Application\38.0.2125.104\fileA.exe
OR Update\1.3.24.15\fileB.exe
rather than showing
C:\Program Files (x86)\Google\Chrome\Application\38.0.2125.104\fileA.exe
OR
C:\Program Files (x86)\Google\Update\1.3.24.15\fileB.exe
XAML code
<Window x:Class="FileFinder.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="FileCopier"
WindowStartupLocation="CenterScreen" Width="1366" Height="758">
<Grid Background="LavenderBlush">
<Label Height="40" Margin="240,0,234,0" Name="label1" VerticalAlignment="Top" FontSize="28" HorizontalContentAlignment="Center" Foreground="DarkSeaGreen" FontWeight="Bold" FontFamily="Broadway">Welcome To</Label>
<Label Height="55" Margin="194,35,194,0" Name="label2" VerticalAlignment="Top" HorizontalContentAlignment="Center" FontWeight="Bold" FontSize="45" Foreground="Chocolate" FontFamily="Colonna MT">FILE FINDER</Label>
<TextBox IsReadOnly="True" AutoWordSelection="True" VerticalScrollBarVisibility="Auto" Margin="475.857,211,20,21" Name="textbox1" Background="LavenderBlush" Opacity="0.7" ScrollBar.Scroll="Scroll" BorderThickness="0" FontSize="16" TextWrapping="Wrap"></TextBox>
<Button ToolTip="Click to search exe files" Height="45" HorizontalAlignment="Left" Margin="366,96,0,0" Name="button1" VerticalAlignment="Top" Width="112" Background="LavenderBlush" BorderThickness="1" BorderBrush="DarkSeaGreen" FontSize="24" FontWeight="Bold" Foreground="DarkSeaGreen" Click="button1_Click" FontFamily="Broadway" Cursor="Hand">.exe</Button>
<Button ToolTip="Click to search dll files" Margin="602,96,0,0" Name="button2" Background="LavenderBlush" BorderBrush="DarkSeaGreen" Foreground="DarkSeaGreen" FontSize="24" FontWeight="Bold" Click="button2_Click" FontFamily="Broadway" Cursor="Hand" Height="45" VerticalAlignment="Top" HorizontalAlignment="Left" Width="123">.dll</Button>
<Button Background="LavenderBlush" BorderBrush="DarkSeaGreen" FontSize="24" FontWeight="Bold" Foreground="DarkSeaGreen" Height="45" HorizontalAlignment="Right" Margin="0,96,383,0" Name="button3" VerticalAlignment="Top" Width="122" Click="button3_Click" FontFamily="Broadway">All</Button>
<Label FontFamily="Broadway" FontSize="28" FontWeight="Bold" Foreground="Black" Height="40" HorizontalContentAlignment="Center" Margin="12,165,0,0" Name="label3" VerticalAlignment="Top" HorizontalAlignment="Left" Width="230.069" Opacity="0.6">Filename</Label>
<Label FontFamily="Broadway" FontSize="28" FontWeight="Bold" Foreground="Black" Height="40" HorizontalContentAlignment="Center" Margin="0,165,234,0" Name="label4" VerticalAlignment="Top" Opacity="0.6" HorizontalAlignment="Right" Width="86.627">Path</Label>
<Button Name="button4" Click="button4_Click" Width="32" Height="32" HorizontalAlignment="Right" Margin="0,173,175,0" VerticalAlignment="Top" BorderThickness="0" Background="LavenderBlush" ToolTip="PageUp">
<StackPanel>
<Image Source="C:\Users\Vipul.Sharma\Documents\Visual Studio 2008\Projects\FileFinder\FileFinder\PageUp.png"></Image>
</StackPanel>
</Button>
<Button Name="button5" Click="button5_Click" Width="32" Height="32" HorizontalAlignment="Right" Margin="0,173,140,0" VerticalAlignment="Top" BorderThickness="0" Background="LavenderBlush" ToolTip="PageUp">
<StackPanel>
<Image Source="C:\Users\Vipul.Sharma\Documents\Visual Studio 2008\Projects\FileFinder\FileFinder\PageDown.png" Opacity="0.7"></Image>
</StackPanel>
</Button>
<TextBox IsReadOnly="True" AutoWordSelection="True" VerticalScrollBarVisibility="Visible" Margin="20,211,0,21" Name="textbox2" Background="LavenderBlush" Opacity="0.7" ScrollBar.Scroll="Scroll" BorderThickness="0" FontSize="16" TextWrapping="Wrap" HorizontalAlignment="Left" Width="345.818"></TextBox>
<TextBox IsReadOnly="True" AutoWordSelection="True" VerticalScrollBarVisibility="Visible" HorizontalAlignment="Left" Margin="371.54,211,0,21" Name="textBox3" Width="106.46" Background="LavenderBlush" Opacity="0.7" ScrollBar.Scroll="Scroll" BorderThickness="0" FontSize="16" TextWrapping="Wrap"></TextBox>
<Label FontFamily="Broadway" FontSize="28" FontWeight="Bold" Foreground="Black" Height="40" HorizontalAlignment="Left" HorizontalContentAlignment="Center" Margin="305.806,165.764,0,0" Name="label5" Opacity="0.6" VerticalAlignment="Top" Width="230.069">Extension</Label>
<Button Background="LavenderBlush" BorderBrush="DarkSeaGreen" FontFamily="Broadway" FontSize="24" FontWeight="Bold" Foreground="DarkSeaGreen" Height="45" HorizontalAlignment="Right" Margin="0,95.743,143,0" Name="button6" VerticalAlignment="Top" Width="122" Click="button6_Click">GetFile</Button>
</Grid>
C# code
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Controls.Primitives;
namespace FileFinder
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
List<String> files = new List<String>();
String[] extensions = new[] { "*.exe" };
foreach (String extension in extensions)
{
String[] lol = Directory.GetFiles(#"mypath", "*.exe", SearchOption.AllDirectories);
foreach (String file in lol)
files.Add(file);
}
textbox1.Clear();
textBox3.Clear();
textbox1.Clear();
for (int i = 0; i < files.Count; i++)
{
textbox2.Text += Path.GetFileNameWithoutExtension(files[i]) + "\n";
textBox3.Text += Path.GetExtension(files[i]) + "\n";
textbox1.Text += files[i] + "\n";
}
List<string> lstResult = new List<string>();
for (int i = 0; i < files.Count; i++)
{
lstResult.Add(Path.GetFileNameWithoutExtension(files[i]) + "," + Path.GetExtension(files[i])+"," + Path.GetFullPath(files[i]));
}
File.WriteAllLines(#"C:\BigB.csv", lstResult.ToArray());
}
private void Scroll(object sender, ScrollEventArgs e)
{
if (sender == textbox1 || sender == textBox3)
{
textbox1.ScrollToVerticalOffset(e.NewValue);
textBox3.ScrollToVerticalOffset(e.NewValue);
}
else
{
textbox1.ScrollToVerticalOffset(e.NewValue);
textBox3.ScrollToVerticalOffset(e.NewValue);
}
}
//WHAT I HAVE SEEN AND TRIED
private void button6_Click(object sender, RoutedEventArgs e)
{
ReadCSV("BigB.csv");
textbox2.Text += name;
textbox1.Text += extension;
textBox3.Text += path;
}
public class InOrder
{
public string name { get; set; }
public string extension { get; set; }
public string path { get; set; }
public InOrder(string n, string ext, string p)
{
name = n;
extension = ext;
path = p;
}
}
public IEnumerable<InOrder> ReadCSV(string fileName)
{
// We change file extension here to make sure it's a .csv file.
string[] collectBack = File.ReadAllLines(System.IO.Path.ChangeExtension(#"C:\BigB.csv", ".csv"));
// lines.Select allows me to project each line as a InOrder.
// This will give me an IEnumerable<InOrder> back.
return
{
string[] data = collectBack.Split(';');
// We return a person with the data in order.
return new InOrder(data[0], data[1], (data[2]));
});
}
}

You're working with XAML, so you should bind to your control instead of doing textbox2.Text = "something". Once you do that you don't need any of those "Name" properties in your XAML code. If you do need to name anything, use proper, descriptive names: textbox2 doesn't tell me anything.
Why do foreach (String extension in extensions) when you never use extension?
IMHO most of the code in button1_Click should be moved to separate classes: one class to retrieve the list of files, another to write the list of files to a file.
Why do for (int i = 0; i < files.Count; i++) when you can simply do foreach (var file in files)?
Why store the result of Directory.GetFiles in the (badly named) variable lol when you could simply use the AddRange method of files?
If you want to show Update\1.3.24.15\fileB.exe instead of C:\Program Files (x86)\Google\Update\1.3.24.15\fileB.exe, simply use the string.Replace method to replace C:\Program Files (x86)\Google\ with string.Empty. You should have no trouble finding C# code to read the contents of a file.
To me InOrder is a bad class name, since it doesn't tell me what it contains. FileData or FileProperties makes more sense. You should use this class more often, e.g. instead of getting List<String> files, parse the result Directory.GetFiles immediately and convert it to a List<FileData> and iterate over these when assigning textbox2, textBox3, textbox1,...
Why is there a call to System.IO.Path.ChangeExtension?
ReadCSV returns an IEnumerable<InOrder>, but you don't loop through the results.
Why require a filename to be passed to ReadCSV when you don't use it?
public string name { get; set; } violates Microsoft's naming rules: Properties should be PascalCase.

Why use those intermediate steps?
List<string> lstResult = new List<string>();
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder();
StringBuilder sb3 = new StringBuilder();
foreach (String lol in Directory.GetFiles(#"mypath", "*.exe", SearchOption.AllDirectories);s)
{
lstResult.Add(Path.GetFileNameWithoutExtension(lol) + "," + Path.GetExtension(lol)+"," + Path.GetFullPath(lol);
sb1.AppendLine(lol);
sb2.AppendLine(Path.GetFileNameWithoutExtension(lol));
sb3.AppendLine(Path.GetExtension(lol));
}
File.WriteAllLines(#"C:\BigB.csv", lstResult.ToArray());
textbox1.Text = sb1.ToString();
textbox2.Text = sb2.ToString();
textbox3.Text = sb3.ToString();

Related

delayed trigger for calculation with data binding

I'm very new to WPF and currently learning the concepts of data binding.
my simplified XAML code. besides my problem (below) it works fine - quick and dirty placing of objects via GUI, will be cleaned up once works:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="60"/>
<RowDefinition/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
</Grid>
<Grid Grid.Row="1">
<GroupBox Header="Change Type:" Height="95" Width="100" VerticalAlignment="Top" Margin="270,4,422,0" >
<StackPanel>
<RadioButton x:Name="RbtAdd" HorizontalAlignment="Left" Margin="5" VerticalAlignment="Top" GroupName="modGroup" Checked="ModeRadio_Checked">
<WrapPanel>
<TextBlock Text="Add" Foreground="Green"/>
</WrapPanel>
</RadioButton>
<RadioButton x:Name="RbtPull" HorizontalAlignment="Left" Margin="5" VerticalAlignment="Top" GroupName="modGroup" Checked="ModeRadio_Checked">
<WrapPanel>
<TextBlock Text="Pull" Foreground="Blue"/>
</WrapPanel>
</RadioButton>
<RadioButton x:Name="RbtModify" HorizontalAlignment="Left" Margin="5" VerticalAlignment="Top" GroupName="modGroup" Checked="ModeRadio_Checked">
<WrapPanel>
<TextBlock Text="Modify" Foreground="DarkGray"/>
</WrapPanel>
</RadioButton>
</StackPanel>
</GroupBox>
<TextBlock x:Name="txtCurStock" HorizontalAlignment="Left" Margin="330,181,0,0" TextWrapping="Wrap" Text="{Binding Path=CurrentStock}" VerticalAlignment="Top" FontSize="20" FontWeight="Bold" TextAlignment="Center"/>
<Label Content="Current stock:" HorizontalAlignment="Left" Margin="289,156,0,0" VerticalAlignment="Top"/>
<Label x:Name ="lblOperation" Content="Stock to Pull:" HorizontalAlignment="Left" Margin="507,156,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="txtEntry" HorizontalAlignment="Left" Height="32" Margin="489,181,0,0" TextWrapping="Wrap" TextAlignment="Center" Text="{Binding Path=ModEntry}" VerticalAlignment="Top" Width="120" FontSize="20" FontWeight="Bold" TextChanged="TxtEntry_TextChanged"/>
<Label Content="New Stock" HorizontalAlignment="Right" Margin="714,156,0,0" VerticalAlignment="Top" Width="68"/>
<TextBlock Text="{Binding Path=NewStock}" HorizontalAlignment="Right" Margin="0,186,10,0" TextAlignment="Center" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="20" FontWeight="Bold" Width="68"/>
<TextBox x:Name="txtComment" HorizontalAlignment="Left" Height="86" Margin="289,233,0,0" TextWrapping="Wrap" Text="{Binding Path=ModEntry}" VerticalAlignment="Top" Width="493"/>
<Label Content="Comment:" HorizontalAlignment="Left" Margin="289,207,0,0" VerticalAlignment="Top"/>
<TextBlock x:Name ="txtModindicator" HorizontalAlignment="Left" Margin="433,181,0,0" TextWrapping="Wrap" Text="-" FontSize="20" FontWeight="Bold" VerticalAlignment="Top"/>
<TextBlock x:Name ="txtResindicator" HorizontalAlignment="Left" Margin="663,182,0,0" TextWrapping="Wrap" Text="=" FontSize="20" FontWeight="Bold" VerticalAlignment="Top"/>
</Grid>
</Grid>
now the shortened c# code:
using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace SomeWPF
{
/// <summary>
/// Interaction logic for ModifyWindow.xaml
/// </summary>
public partial class MainWindow : INotifyPropertyChanged
{
public enum Mymode
{
add,
pull,
modify
}
public Mymode mode;
public MainWindow()
{
DataContext = this;
InitializeComponent();
CurrentStock = 5;
RbtPull.IsChecked = true;
ModEntry = 1;
}
private void ModeRadio_Checked(object sender, RoutedEventArgs e)
{
if (sender != null)
{
if (sender.Equals(RbtAdd))
{
mode = Mymode.add;
txtModindicator.Text = "+";
txtComment.Text = "Add";
lblOperation.Content = "Stock to Add:";
}
else if (sender.Equals(RbtPull))
{
mode = Mymode.pull;
txtModindicator.Text = "-";
txtComment.Text = "Pull";
lblOperation.Content = "Stock to Pull:";
}
else
{
mode = Mymode.modify;
txtModindicator.Text = "~";
lblOperation.Content = "Corrected Quantity:";
txtComment.Text = "Mod";
}
TxtEntry_TextChanged(sender, null);
}
}
private void TxtEntry_TextChanged(object sender, TextChangedEventArgs e)
{
if (mode == Mymode.add)
{
NewStock = CurrentStock + ModEntry;
}
else if (mode == Mymode.pull)
{
NewStock = CurrentStock - ModEntry;
}
else
{
NewStock = ModEntry;
}
}
#region Binding Stuff
private int _newstock;
public int NewStock
{
get
{
return _newstock;
}
set
{
if (_newstock != value)
{
_newstock = value;
OnPropertyChanged();
}
}
}
private int _modentry;
public int ModEntry
{
get
{
return _modentry;
}
set
{
if (_modentry != value)
{
_modentry = value;
OnPropertyChanged();
}
}
}
private int _currentstock;
public int CurrentStock
{
get
{
return _currentstock;
}
set
{
if (_currentstock != value)
{
_currentstock = value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}
So this window is a popup in a little program for an inventory storage for the users to enter movements of the inventory.
everything loads fine so far and I now wanted to do the quite simple calculation part. with "old" winforms c# you'd just take the values and update the text property of the result "manually" but of course we (I) want to learn new stuff and do stuff with data binding.
The code also does the calculation, but the trigger is somehow not what I want.
let's say current stock is 5
when window loads, the mode is set to Pull (RbtPull) and the user entry (Binding to ModEntry) is set to 1 via code. The NewStock therefore should be 4 which displays correctly. (yey)
Also the comment field (for debugging for now) displays the ModEntry value 1.
so far so good.
Now I enter 3 in the Stock to Pull field, but nothing happens. (I want it to react "realtime"). The new Stock is still displayed as 4, the comment is still displayed as 1.
When I leave the field (and click into the comment field) - the property change is detected and the Comment Field shows also 3 (=ModEntry) - so it's not "realtime" but only triggers when the field is losing focus, but that would be also acceptable.
The real problem is: The new Stock stays 4 and does not calculate.
Now when I enter the Stock to Pull field again and change the value to let's say 5, the New Stock field updates to 2 (so to the value I entered before 5-3=2)
Overwriting the field with again 5 will change the new Stock to 0.
So it's always "one step behind".
From what I have found i have an idea, that I need some kind of Binding Converter instead of my method of calculating things, but I can't really find anything suitable and am not familiar enough yet with data binding. Have tried out some things already directly in the binding variable code but none worked. If anyone could hint me in the right direction I'd be very thankful. (don't need a silver plate solution but just an idea what way to search (e.g. if the sort of binding I use makes sense at all or if there's something I have to add etc.).
Thanks a lot!
PS: of course if someone is motivated to give a silver plate solution I'd also be grateful. :) - and sorry for the bad english, no native speaker.
#nosale 's second link (see comments) provided the answer to the Problem.
Setting both XAML fields txtEntry and the Result field to UpdateSourceTrigger=PropertyChanged solved the issue.
so the correct block Looks like this now without changes to the c# code:
<Label Content="Current stock:" HorizontalAlignment="Left" Margin="289,156,0,0" VerticalAlignment="Top"/>
<Label x:Name ="lblOperation" Content="Stock to Pull:" HorizontalAlignment="Left" Margin="507,156,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="txtEntry" HorizontalAlignment="Left" Height="32" Margin="489,181,0,0" TextWrapping="Wrap" TextAlignment="Center" Text="{Binding Path=ModEntry, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120" FontSize="20" FontWeight="Bold" TextChanged="TxtEntry_TextChanged"/>
<Label Content="New Stock" HorizontalAlignment="Right" Margin="714,156,0,0" VerticalAlignment="Top" Width="68"/>
<TextBlock Text="{Binding Path=NewStock, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Right" Margin="0,186,10,0" TextAlignment="Center" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="20" FontWeight="Bold" Width="68"/>
<TextBox x:Name="txtComment" HorizontalAlignment="Left" Height="86" Margin="289,233,0,0" TextWrapping="Wrap" Text="{Binding Path=ModEntry}" VerticalAlignment="Top" Width="493"/>
<Label Content="Comment:" HorizontalAlignment="Left" Margin="289,207,0,0" VerticalAlignment="Top"/>
Reason is, that textboxes have a Default UpdateSourceTrigger=LostFocus and not PropertyChanged to prevent updates with user having entered typos.
something new learned: WPF is cool and automatically handles non plausible values like null or strings and marks the field red! :)
thanks again for the links!

C# WPF create checkboxes for each item in listview

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

How do I bind the Textbox from List?

I need only to bind the Textboxes. I created a next and previous button this works but nothing is on the Textbox. What do I wrong? How do I get the items form the List?
The Read from the Database:
void read()
{
using (var nwe = new NORTHWNDEntities())
{
var objctx = (nwe as IObjectContextAdapter).ObjectContext;
ObjectQuery<Employee> query = new ObjectQuery<Employee>(
"SELECT VALUE n from NORTHWNDEntities.Employees as n", objctx);
List<Employee> results = query.ToList();
cursor = (CollectionView)CollectionViewSource.GetDefaultView(results);
}
}
private void countposition()
{
labelRead.Content = "Read " + (cursor.CurrentPosition + 1) + " to " + cursor.Count;
}
private void buttonNext_Click(object sender, RoutedEventArgs e)
{
if(cursor.CurrentPosition < cursor.Count -1)
{
cursor.MoveCurrentToNext();
countposition();
}
else
{
MessageBox.Show("No more data");
}
}
private void buttonPrevious_Click(object sender, RoutedEventArgs e)
{
if (cursor.CurrentPosition > 0)
{
cursor.MoveCurrentToPrevious();
countposition();
}
else
{
MessageBox.Show("No more data");
}
}
The UI Code to Bind the Data:
<TextBox x:Name="textBoxID" HorizontalAlignment="Left" Height="23" Margin="163,79,0,0" TextWrapping="Wrap" Text="{Binding Path=EmployeeID}" IsReadOnly="True" VerticalAlignment="Top" Width="87"/>
<Label x:Name="labelFirstNAme" Content="First Name" HorizontalAlignment="Left" Margin="52,157,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="textBoxFirstName" HorizontalAlignment="Left" Height="23" Margin="163,157,0,0" TextWrapping="Wrap" Text="{Binding Path=FirstName}" VerticalAlignment="Top" Width="145"/>
<Label x:Name="labelLastName" Content="Last Name" HorizontalAlignment="Left" Margin="52,224,0,0" VerticalAlignment="Top" Width="67"/>
<TextBox x:Name="textBoxLastName" HorizontalAlignment="Left" Height="23" Margin="163,224,0,0" TextWrapping="Wrap" Text="{Binding Path=LastName}" VerticalAlignment="Top" Width="145"/>
<Label x:Name="labelBirthDate" Content="Birth Date" HorizontalAlignment="Left" Margin="52,307,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.289,0.462" Width="67"/>
<TextBox x:Name="textBoxBirthDate" HorizontalAlignment="Left" Height="23" Margin="163,310,0,0" TextWrapping="Wrap" Text="{Binding Path=BirthDate}" VerticalAlignment="Top" Width="145"/>
Sorry I drank a few beers but TextBox accepts just one value, id est typically .Text="oneStringInstanceOnly".
You would like to bind List<> (that has multiple values / objects / strings / classes) to a TextBox that accepts generally one (usually string) value and that is the reason why you cannot bind a List that contains multiple values to a TexBox that accepts one value. TextBox is not a DataGridView or ListBox that accept multiple values / data tables. Evenutally you could assign the TexBox with the first value from the list myTextBox = (myList!=null && myList.Count!=0)?myList[0].ToString():"NoMoreValues";

Windows Phone with XML - Display specific TAGs

I'm developing an app, my "ListBox" displays information an XML file, get the information and display in "TextBox". But i do not want that the "ListBox" and "TextBox" show all XML TAGs.
First as it is now. Second as it should be:
http://infassteste.url.ph/ats.png
http://infassteste.url.ph/dps.jpg
My XML:
<produtos>
<produto>
<codigo>1</codigo>
<descricao>Janela</descricao>
<valor>100.00</valor>
</produto>
<produto>
<codigo>2</codigo>
<descricao>Porta</descricao>
<valor>1000.00</valor>
</produto>
<produto>
<codigo>3</codigo>
<descricao>Cimento</descricao>
<valor>10.00</valor>
</produto>
<produto>
<codigo>4</codigo>
<descricao>Arame</descricao>
<valor>60.00</valor>
</produto>
</produtos>
My Xaml file:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock TextWrapping="Wrap" Text="Quantidade:" Margin="6,235,326,373"/>
<TextBox MaxLength="3" InputScope="Number" HorizontalAlignment="Left" Height="71" Margin="135,215,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="86" Name="Qtd"/>
<Button Content="Adicionar" HorizontalAlignment="Left" Margin="279,212,0,0" VerticalAlignment="Top" Width="148" Click="Button_Enviar"/>
<TextBlock HorizontalAlignment="Left" Margin="10,322,0,0" TextWrapping="Wrap" Text="Lista de Produtos:" VerticalAlignment="Top" Height="30" Width="166"/>
<ListBox x:Name="listBox1"
Height="192" Width="456"
HorizontalAlignment="Center"
VerticalAlignment="Top"
BorderThickness="5"
Padding="5"
BorderBrush="Blue"
Background="Black"
FontSize="30"
/>
<TextBox x:Name="txtList" IsReadOnly="True" HorizontalAlignment="Left" Height="267" Margin="0,357,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="456"/>
</Grid>
My Code:
namespace InfamatPocket
{
public partial class Produtos : PhoneApplicationPage
{
public Produtos()
{
InitializeComponent();
IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
try
{
XDocument doc = XDocument.Load(store.OpenFile("im.xml", FileMode.Open, FileAccess.Read));
this.listBox1.ItemsSource = from query in doc.Descendants("produto") select query.Value;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void Button_Enviar(object sender, RoutedEventArgs e)
{
String dedos = " " + Qtd.Text + " | " + listBox1.SelectedItem;
String dados = "\nProduto: " + listBox1.SelectedItem + "\nQuantidade: " + Qtd.Text;
MessageBox.Show(dados);
if (!string.IsNullOrEmpty(dados))
{
txtList.Text += dedos + "\n";
}
// this.listBox2.ItemsSource = "Quantidade:" + Qtd.Text + " | " + listBox1.SelectedItem;
}
}
}
Make your LINQ query return a model having two property, descricao and valor for example (I'm using anonymous type here for the sake of simplicity) :
listBox1.ItemsSource = from query in doc.Descendants("produto")
select new
{
descricao = (string)query.Element("descricao"),
valor = (string)query.Element("valor")
};
Setup <ItemTemplate> for ListBox so each item in ListBox able to display multiple values in the way we want :
<ListBox x:Name="listBox1"
.....
.....
HorizontalContentAlignment="Stretch"
>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding descricao}"/>
<TextBlock Grid.Column="1" Text="{Binding valor}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Accessing items in DataTemplate using Visual Tree Helper in ListBox

I have the following DataTemplate:
<DataTemplate x:Key="ToDoListBoxItemTemplate">
<Grid x:Name="item2Expanded" HorizontalAlignment="Left" VerticalAlignment="Top" Width="480" Background="{Binding Converter={StaticResource RowColour}}" MinHeight="81">
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Width="420" Margin="60,0,0,0">
<TextBox x:Name="taskTitle" HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding ItemName}" VerticalAlignment="Top" Width="420" Background="{x:Null}" BorderBrush="{x:Null}" CaretBrush="#FF0080FF" SelectionBackground="#FFCFCFCF" Foreground="#FF4E4E4E" BorderThickness="3,3,3,6" FontSize="29.333" Style="{StaticResource listTextBoxTemplate}" InputScope="Text" SelectionForeground="#FF4E4E4E" KeyUp="taskTitle_KeyUp" LostFocus="taskTitle_LostFocus" Tap="taskTitle_Tap" IsReadOnly="True" Margin="0,1,0,0" DoubleTap="taskTitle_DoubleTap"/>
<TextBox x:Name="taskDetail" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Tea is an essential English beverage, it has a nice calming effect, and is often served alongside biscuits." VerticalAlignment="Top" Width="420" Background="{x:Null}" BorderBrush="{x:Null}" CaretBrush="#FF0080FF" SelectionBackground="#FFCFCFCF" Foreground="#FF878787" BorderThickness="3,0,3,6" FontSize="21.333" Style="{StaticResource listTextBoxTemplate}" InputScope="Text" SelectionForeground="#FF878787" Margin="0,-20,0,0" KeyUp="taskDetail_KeyUp" LostFocus="taskDetail_LostFocus" Padding="2,5,2,2" IsHitTestVisible="False"/>
<Grid Height="170" Margin="0,-20,0,0">
<Button x:Name="chooseDateButton" Content="27/06/2013" HorizontalAlignment="Left" Margin="6,13,0,0" VerticalAlignment="Top" BorderBrush="#FF959595" Foreground="#FF959595" Width="157" HorizontalContentAlignment="Left" FontSize="20" Style="{StaticResource selectorButtonTemplate}"/>
<Button x:Name="chooseTimeButton" Content="12:00" HorizontalAlignment="Left" Margin="146,13,0,0" VerticalAlignment="Top" BorderBrush="#FF959595" Foreground="#FF959595" Width="99" HorizontalContentAlignment="Left" FontSize="20" Style="{StaticResource selectorButtonTemplate}"/>
<Button x:Name="setOrClearButton" Content="REMIND ME" HorizontalAlignment="Left" Margin="228,13,0,0" VerticalAlignment="Top" BorderBrush="#FF959595" Foreground="White" Width="180" FontSize="20" Background="#FF959595" Style="{StaticResource greyButtonTemplate}"/>
<Button x:Name="deleteButton" Content="DELETE TASK" HorizontalAlignment="Left" Margin="6,85,0,0" VerticalAlignment="Top" BorderBrush="#FFEE4747" Foreground="White" Width="180" FontSize="20" Background="#FFEE4747" Style="{StaticResource redButtonTemplate}"/>
<Image x:Name="retractButton" Margin="347,107,21,11" Source="/Assets/retract.png" Stretch="Fill" Tap="retractButton_Tap"/>
</Grid>
</StackPanel>
<CheckBox x:Name="checkBox" IsChecked="{Binding IsComplete, Mode=TwoWay}" Content="" HorizontalAlignment="Left" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="{x:Null}" Width="72" BorderThickness="0" Template="{StaticResource checkBoxTemplate}" Checked="checkBox_Checked" Unchecked="checkBox_Unchecked"/>
</Grid>
</DataTemplate>
Where the Grid item2Expanded is placed dynamically in a ListBox (Name="allToDoItemsListBox"). Text is added to each item via bindings.
The image retractButton has Tap="retractButton_Tap", As shown in the code:
private void retractButton_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
if (isItemExpanded == true)
{
// Compacts current item
itemGrid.Height = taskTitle.ActualHeight; // Restores itemGrid height to fit only taskTitle
taskTitle.IsReadOnly = true; // taskTitle becomes only double-tap editable, single tap to expand once more
taskDetail.IsHitTestVisible = false; // Stops overlapping taps
isItemExpanded = false;
}
// Adds the event handler for single tap event
tapTimer.Tick += new EventHandler(tapTimer_Tick);
tapTimer.Start();
}
private void tapTimer_Tick(object sender, EventArgs e)
{
// Stop timer
tapTimer.Tick -= new EventHandler(tapTimer_Tick);
tapTimer.Stop();
// Rest of the single tap function
if (isItemExpanded == false)
{
taskDetail.IsHitTestVisible = true;
taskDetail.IsEnabled = false;
// Expands current item
itemGrid.Height = double.NaN; // Sets itemGrid height to auto
isItemExpanded = true;
// Yeah... don't ask.
// Stops temporary text highlighting/auto jumping to keyboard
taskTitle.IsEnabled = false;
taskTitle.IsEnabled = true;
taskDetail.IsEnabled = true;
}
}
But I cannot access itemGrid, taskTitle, or taskDetail for this specific item. And I have no idea how to pass them to the tapTimer_Tick function.
I have been able to use the Tag="{binding itemID}" on elements, but that still hasn't allowed me to solve this issue.
How do I find the grid item2Expanded that the Tap originated from, and then access elements in the same grid by name?
If I want to access the same element as was clicked, then it's easy:
private void taskTitle_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
TextBox taskTitle = (TextBox)sender;
taskTitle.IsEnabled = false;
}
I've been trying to work out how to use Visual Tree Helper to solve this problem, but I have no idea how to do it.

Categories