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";
Related
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!
I would like to add the next line text in a textbox to a new line in gridview.
This is my current code:
<Label x:Name="label1" Content="URL :" HorizontalAlignment="Left" Margin="22,27,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="textBox1" HorizontalAlignment="Left" Height="146" Margin="64,30,0,0" TextWrapping="Wrap" Text="Enter URLs Here" GotFocus="TextBox_GotFocus" VerticalAlignment="Top" Width="555" AcceptsReturn="True"/>
<Button x:Name="button1" Content="Check & Index" HorizontalAlignment="Left" Margin="652,19,0,0" VerticalAlignment="Top" Width="134" Height="40" Click="Button1_Click"/>
<Grid Margin="0,0,0,0.333">
<DataGrid x:Name="dataGrid1" HorizontalAlignment="Left" Height="459" VerticalAlignment="Top" Width="1700" Margin="22,185,0,-121.666" AutoGenerateColumns="True" SelectionChanged="dataGrid_SelectionChanged">
<DataGrid.Columns>
<DataGridTextColumn Header="URL" Width="150" Binding="{Binding URL}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
Code Behind:
private void Button1_Click(object sender, RoutedEventArgs e)
{
dataGrid1.Items.Add(new { URL = textBox1.Text});
}
Current code just inserts all text from textBox1 into 1 single column. What I want is let's say I have 5 lines in textBox1, each line should be added into new row.
You can split the lines of the textbox1.
List<string> Urllines = theText.Split(
new[] { Environment.NewLine },
StringSplitOptions.RemoveEmptyEntries
).ToList();
and then
private void Button1_Click(object sender, RoutedEventArgs e)
{
foreach(string strUrl in Urllines)
dataGrid1.Items.Add(new { URL = strUrl});
}
We use RemoveEntryEmpties as the second parameter to avoid empty results.
I have 2 buttons and they do the same on different controls. How can i make this better? Because now i too much copy/paste. Here is image and code.
enter image description here
private void button_ClickOld(object sender, RoutedEventArgs e)
{
TextBoxOld.Text = SelectCatalog();
if (File.Exists(TextBoxOld + ConfigFilePath))
{
GetClientProperty(TextBoxOld.Text);
UpdateOldLabel();
}
else
{
LogsTextBox.AppendText("\nWrong folder selected - Config file doesn't exist");
}
}
private void button_ClickNew(object sender, RoutedEventArgs e)
{
TextBoxNew.Text = SelectCatalog();
if (File.Exists(TextBoxNew + ConfigFilePath))
{
GetClientProperty(TextBoxNew.Text);
UpdateNewLabel();
}
else
{
LogsTextBox.AppendText("\nWrong folder selected - Config file doesn't exist");
}
}
xaml
<Button x:Name="ButtonOld" Content="..." HorizontalAlignment="Left" Margin="149,35,0,0" VerticalAlignment="Top" Width="25" Click="button_ClickOld"/>
<TextBox x:Name="TextBoxOld" HorizontalAlignment="Left" Height="23" Margin="24,35,0,0" Text="" VerticalAlignment="Top" Width="120" IsReadOnly="True"/>
<Button x:Name="ButtonNew" Content="..." HorizontalAlignment="Left" Margin="447,35,0,0" VerticalAlignment="Top" Width="25" Click="button_ClickNew"/>
<TextBox x:Name="TextBoxNew" HorizontalAlignment="Left" Height="23" Margin="322,35,0,0" Text="" VerticalAlignment="Top" Width="120" IsReadOnly="True"/>` <Label x:Name="OldNameLabel" Content="Name" HorizontalAlignment="Left" Margin="24,70,0,0" VerticalAlignment="Top"/>
<Label x:Name="OldIpLabel" Content="IP" HorizontalAlignment="Left" Margin="24,100,0,0" VerticalAlignment="Top"/>
<Label x:Name="OldWebpageUriLabel" Content="WebpageUri" HorizontalAlignment="Left" Margin="24,130,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="OldConnectionStringTextBox" Text="ConnectionString" HorizontalAlignment="Left" Margin="24,160,0,0" Width="120"
VerticalAlignment="Top" Background="Linen" BorderThickness="0" IsReadOnly="True"/>
<Label x:Name="NewNameLabel" Content="Name" HorizontalAlignment="Left" Margin="322,70,0,0" VerticalAlignment="Top"/>
<Label x:Name="NewIpLabel" Content="IP" HorizontalAlignment="Left" Margin="322,100,0,0" VerticalAlignment="Top"/>
<Label x:Name="NewWebpageUriLabel" Content="WebpageUri" HorizontalAlignment="Left" Margin="322,130,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="NewConnectionStringTextBox" Text="ConnectionString" HorizontalAlignment="Left" Margin="322,160,0,0" Width="120"
VerticalAlignment="Top" Background="Linen" BorderThickness="0" IsReadOnly="True"/>
<Label x:Name="ArrowLabel" Content="<-" HorizontalAlignment="Left" Margin="221,14,0,0" VerticalAlignment="Top" FontSize="30" />
<Label x:Name="OldVersionTextBoxLabel" Content="Old Version:" HorizontalAlignment="Left" Margin="24,4,0,0" VerticalAlignment="Top"/>
<Label x:Name="NewVersionTextBoxLabel" Content="New Version:" HorizontalAlignment="Left" Margin="325,4,0,0" VerticalAlignment="Top"/>`
By the looks of your it, you don't understand MVVM and SOLID principles. If you truly want to take advantage of WPF, you must first learn MVVM, and to truly take advantage of MVVM, you need to understand SOLID. To reduce the burden of verbose XAML and boiler plate code, you should take advantage of MVVM frameworks, Caliburn.Micro is super easy to use but require you to have a good architecture to be able to fully utilize it.
Further, using MVVM will make your XAML code so much simpler. Old Version and New Version section will just have one UserControl and may look like
<views:VersionView DataContext={Binding OldVersionViewModel}/>
<views:VersionView DataContext={Binding NewVersionViewModel}/>
You will save yourself a lot of pain and make you delighted you chose WPF for your UI once you learn the power of MVVM.
But if this is just a small project and you insist on using code behind, you can do
private void button_ClickOld(object sender, RoutedEventArgs e)
{
SelectVerifyAndLog(TextBoxOld, UpdateOldLabel);
}
private void button_ClickNew(object sender, RoutedEventArgs e)
{
SelectVerifyAndLog(TextBoxNew, UpdateNewLabel);
}
void SelectVerifyAndLog(TextBox textBox, Action updateLabel)
{
textBox.Text = SelectCatalog();
if (File.Exists(textBox + ConfigFilePath))
{
GetClientProperty(textBox.Text);
updateLabel();
}
else
{
LogsTextBox.AppendText("\nWrong folder selected - Config file doesn't exist");
}
}
1) You can reuse your code
private void button_ClickOld(object sender, RoutedEventArgs e)
{
ButtonHelper(TextBoxOld);
}
private void button_ClickNew(object sender, RoutedEventArgs e)
{
ButtonHelper(TextBoxNew);
}
void ButtonsHelper(TextBox textBox) {
TextBoxNew.Text = SelectCatalog();
if (File.Exists(textBox + ConfigFilePath))
{
GetClientProperty(textBox.Text);
UpdateNewLabel();
}
else
{
LogsTextBox.AppendText("\nWrong folder selected - Config file doesn't exist");
}
}
2) In WPF, use MVVM, otherwise you just don't have advantages of WPF
3) If you have many groups of controls like you marked on your picture and they have much of code, make them controls. And each of them will contain it's own xaml, it's own code, and you can reuse it. It's not necessary to put all the xaml in one file.
I don't know how to get text from "firstBox" and "secondBox" after button click.
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<!-- some code -->
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Data}" VerticalAlignment="Top" Height="18" Width="100" FontSize="13.333" Margin="162,9,0,0"/>
<TextBlock HorizontalAlignment="Left" Margin="0,35,0,0" TextWrapping="Wrap" Text="{Binding D_gospodarzy}" FontSize="14.667" VerticalAlignment="Top" Height="59" Width="100"/>
<TextBlock HorizontalAlignment="Center" Margin="268,35,7,0" TextWrapping="Wrap" Text="{Binding D_gosci}" FontSize="14.667" VerticalAlignment="Top" Width="100" Height="59"/>
<TextBox x:Name="firstBox" ... />
<Button Content="Click" " Click="Button_Click_1"/>
<TextBox x:Name="secondBox" ... />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
I get only the object
private void Button_Click_1(object sender, RoutedEventArgs e)
{
var myobject = (sender as Button).DataContext;
}
There are cuple of ways to do it, for example you can traverse the VisualTree of clicked button's parent and retrive TextBox with the name you want. In this case, I would take advantage of an extension method written by yasen in this answer.
Then it can look for example like this:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
var parent = (sender as Button).Parent;
TextBox firstOne = parent.GetChildrenOfType<TextBox>().First(x => x.Name == "firstBox");
Debug.WriteLine(firstOne.Text);
}
Remember to put an extension method somewhere in a static class:
public static class Extensions
{
public static IEnumerable<T> GetChildrenOfType<T>(this DependencyObject start) where T : class
{
// rest of the code
Here's how to get the text..
String text1 = firstBox.Text;
String text2 = secondBox.Text;
note: firstBox and secondBox must be class members to use them in different class methods.
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();