Problem using a global variable in an LDAP request - c#

My goal is to retrieve the OU names from an LDAP directory and according to each OU name display its sub OU.
All this in C# with a WPF interface.
My OU retrieval function is ok but the problem is with the display function of the sub OUs according to the chosen OU.
I use a global variable and I think the problem comes from there but I don't really know why.
If you know why I'm in :)
I am available for any question.
Thanks
Maxime
There is the code :
namespace WpfApp1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
comboBoxEntite.ItemsSource = OUList;
afficherOuEntite();
comboBoxSousEntite.ItemsSource = subOuList;
afficherOuSousEntite();
}
private void btnMinimize_Click(object sender, RoutedEventArgs e)
{
WindowState = WindowState.Minimized;
}
private void btnClose_Click(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
DragMove();
}
public void ComboBoxEntite_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
selectedItemF = "LDAP://myserver.lan/OU=" + comboBoxEntite.SelectedItem.ToString() + ",OU=MPG-Users,DC=myserver,DC=lan";
TB.Text = selectedItemF;
}
public void afficherOuEntite()
{
string ldapServer = "LDAP://myserver.lan/OU=MPG-Users,DC=myserver,DC=lan";
DirectoryEntry myLdapConnection = new DirectoryEntry(ldapServer);
DirectorySearcher myDirectorySearcher = new DirectorySearcher(myLdapConnection);
myDirectorySearcher.Filter = "(objectClass=organizationalUnit)";
myDirectorySearcher.PropertiesToLoad.Add("Name");
myDirectorySearcher.SearchScope = SearchScope.OneLevel;
SearchResultCollection resultsOuEntite = myDirectorySearcher.FindAll();
foreach (SearchResult result in resultsOuEntite)
{
string ouName = result.Properties["Name"][0].ToString();
OUList.Add(ouName);
}
}
public void afficherOuSousEntite()
{
DirectoryEntry myLdapConnection = new DirectoryEntry(selectedItemF);
DirectorySearcher myDirectorySearcher = new DirectorySearcher(myLdapConnection);
myDirectorySearcher.Filter = "(objectClass=organizationalUnit)";
myDirectorySearcher.PropertiesToLoad.Add("Name");
myDirectorySearcher.SearchScope = SearchScope.OneLevel;
SearchResultCollection resultsOuSousEntite = myDirectorySearcher.FindAll();
foreach (SearchResult result in resultsOuSousEntite)
{
string ouName = result.Properties["Name"][0].ToString();
subOuList.Add(ouName);
}
}
public List<string> OUList = new List<string>();
public List<string> subOuList = new List<string>();
public static string selectedItemF;
}
}
The result I have concerning the sub-OR is an empty result, as if the search was not based on anything

Related

Reference to other variable

I try to do some minimal app for myself and I have a little problem with selected path. I have the following code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void FilesCountNumberShow_button_Click(object sender, RoutedEventArgs e)
{
// Try to count nu,ber of files in folder
int fCount = Directory.GetFiles(count_path, "*", SearchOption.TopDirectoryOnly).Length;
FilesCountNumber_Label.Content = "Files in folder: " + fCount;
}
private void SelectFolderPath_button_Click(object sender, RoutedEventArgs e)
{
// These code is for open File Dialog and choose older path as count_path
var SelectFolderPath_Dialog = new WinForms.FolderBrowserDialog();
if (SelectFolderPath_Dialog.ShowDialog() == WinForms.DialogResult.OK)
{
string count_path = SelectFolderPath_Dialog.SelectedPath;
MessageBox.Show(count_path);
}
}
}
}
How can I reference the variable count_path in
int fCount = Directory.GetFiles(count_path, "*", SearchOption.TopDirectoryOnly).Length;
I have information that it isn't exist (I think is locla variable in SelectFolderPath_button_Click right? How can I set it global?
I do something that. I add string count_path { get; set; } there:
public partial class MainWindow : Window
{
string count_path { get; set; }
public MainWindow()
{
InitializeComponent();
}
and modify
private void SelectFolderPath_button_Click(object sender, RoutedEventArgs e)
{
var SelectFolderPath_Dialog = new WinForms.FolderBrowserDialog();
if (SelectFolderPath_Dialog.ShowDialog() == WinForms.DialogResult.OK)
{
count_path = SelectFolderPath_Dialog.SelectedPath;
MessageBox.Show(count_path);
}
}
Is this good solution or should it be otherwise done?
Store the selected path in a private field and validate that it has been set:
public partial class MainWindow : Window
{
private string count_path;
public MainWindow()
{
InitializeComponent();
}
private void FilesCountNumberShow_button_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(count_path))
{
MessageBox.Show("You must select a folder first!");
}
else
{
// Try to count nu,ber of files in folder
int fCount = Directory.GetFiles(count_path, "*", SearchOption.TopDirectoryOnly).Length;
FilesCountNumber_Label.Content = "Files in folder: " + fCount;
}
}
private void SelectFolderPath_button_Click(object sender, RoutedEventArgs e)
{
// These code is for open File Dialog and choose older path as count_path
var SelectFolderPath_Dialog = new WinForms.FolderBrowserDialog();
if (SelectFolderPath_Dialog.ShowDialog() == WinForms.DialogResult.OK)
{
count_path = SelectFolderPath_Dialog.SelectedPath;
MessageBox.Show(count_path);
}
}
}
//add assembly reference System.Windows.Forms
private void SelectFolderPath_button_Click(object sender, RoutedEventArgs e)
{
using (var SelectFolderPath_Dialog = new System.Windows.Forms.FolderBrowserDialog())
{
if (SelectFolderPath_Dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string count_path = SelectFolderPath_Dialog.SelectedPath;
MessageBox.Show(count_path);
}
}
}

Auto refresh value in ListViewItem

I'm currently working on an application for an industrial robot. The application connects to all robot controllers in the network and lists them in a ListViewItem. Using a double click on one of the controllers detail information in a second ListVieItem is displayed. Till now I managed to connect to the robot controllers and use the double click to show the information. The problem now is that the value of the variable inside the controller is changing, but I do not know how to adjust my code, so the change will be displayed automatically.
The code I use:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ABB.Robotics.Controllers;
using ABB.Robotics.Controllers.Discovery;
using ABB.Robotics.Controllers.RapidDomain;
using ABB.Robotics.Controllers.IOSystemDomain;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
private NetworkScanner networkScanner = null;
private Controller ctrl = null;
private Controller controller = null;
private Task[] tasks = null;
private NetworkWatcher networkwatcher = null;
private Num rapidNum;
private double VarValue = 0;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
networkScanner = new NetworkScanner();
networkScanner.Scan();
ControllerInfoCollection controllers = networkScanner.Controllers;
networkwatcher = new NetworkWatcher(networkScanner.Controllers);
networkwatcher.Found += new EventHandler<NetworkWatcherEventArgs>(HandleFoundEvent);
networkwatcher.Lost += new EventHandler<NetworkWatcherEventArgs>(HandleLostEvent);
networkwatcher.EnableRaisingEvents = true;
foreach (ControllerInfo controller in controllers)
{
ListViewItem item = new ListViewItem(controller.IPAddress.ToString());
item.SubItems.Add(controller.Id);
item.SubItems.Add(controller.Availability.ToString());
item.SubItems.Add(controller.IsVirtual.ToString());
item.SubItems.Add(controller.SystemName);
item.SubItems.Add(controller.Version.ToString());
item.SubItems.Add(controller.ControllerName);
item.Tag = controller;
this.listControllersView.Items.Add(item);
}
}
private void Form1_Closed(object sender, FormClosedEventArgs e)
{
this.networkwatcher.Lost -= new EventHandler<NetworkWatcherEventArgs>(HandleLostEvent);
this.networkwatcher.Found -= new EventHandler<NetworkWatcherEventArgs>(HandleFoundEvent);
}
private void ListControllersView_DoubleClick(object sender, EventArgs e)
{
ListViewItem itemView = listControllersView.SelectedItems[0];
if(itemView.Tag != null)
{
ControllerInfo controllerInf = (ControllerInfo)itemView.Tag;
if(controllerInf.Availability == ABB.Robotics.Controllers.Availability.Available)
{
if(this.controller != null)
{
this.controller.Logoff();
this.controller.Dispose();
this.controller = null;
}
this.controller = ControllerFactory.CreateFrom(controllerInf);
this.controller.Logon(UserInfo.DefaultUser);
RapidData rd = this.controller.Rapid.GetRapidData("T_ROB1", "RoboDK_Driver", "TESTVAR");
if (rd.Value is Num)
{
rapidNum = (Num)rd.Value;
VarValue = rapidNum.Value;
}
ListViewItem item = new ListViewItem(controller.RobotWare.ToString() + " " + controller.State.ToString() + " " + controller.OperatingMode.ToString() + " " + "VarValue" + " " + VarValue);
this.listOutput.Items.Add(item);
}
else
{
MessageBox.Show("Selected controller not available");
}
}
}
void HandleFoundEvent(object sender, NetworkWatcherEventArgs e)
{
this.Invoke(new
EventHandler<NetworkWatcherEventArgs>(AddControllerToListView),
new Object[] { this, e });
}
void HandleLostEvent(object sender, NetworkWatcherEventArgs e)
{
this.Invoke(new EventHandler<NetworkWatcherEventArgs>(RemoveControllerFromListView),
new Object[] { sender, e });
}
private void AddControllerToListView(object sender, NetworkWatcherEventArgs e)
{
ControllerInfo controllerInfo = e.Controller;
ListViewItem item = new ListViewItem(controllerInfo.IPAddress.ToString());
item.SubItems.Add(controllerInfo.Id);
item.SubItems.Add(controllerInfo.Availability.ToString());
item.SubItems.Add(controllerInfo.IsVirtual.ToString());
item.SubItems.Add(controllerInfo.SystemName);
item.SubItems.Add(controllerInfo.Version.ToString());
item.SubItems.Add(controllerInfo.ControllerName);
item.Tag = controllerInfo;
this.listControllersView.Items.Add(item);
}
private void RemoveControllerFromListView(object sender, NetworkWatcherEventArgs e)
{
foreach(ListViewItem item in this.listControllersView.Items)
{
if((ControllerInfo)item.Tag == e.Controller)
{
this.listControllersView.Items.Remove(item);
break;
}
}
}
}
}

Executing or closing program based on file contents

So my program is a simple form that a user has to read, agree to the terms, and close the window. When the user closes the window it takes their login name and date / time, writes it to a txt file and exits. When the program loads, I want it to check the file for the existing username. If it finds the username, check the date on which it was recorded and if it was within 6 months exit the program. If it was recorded more than 6 months ago, run the program. Obviously, if the reading of the file doesn't find the username I want the program to run as well. Here is my code so far -
namespace EUSAA
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
txtDateTime.Text = DateTime.Now.ToString();
txtUsername.Text = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
btnClose.Visible = false;
chkAgree.Visible = true;
rtbSecurityAwareness.LoadFile("Security Awareness.rtf");
}
private void chkAgree_CheckedChanged(object sender, EventArgs e)
{
if (chkAgree.Checked)
{
btnClose.Visible = true;
}
else btnClose.Visible = false;
}
private void btnClose_Click(object sender, EventArgs e)
{
using (StreamWriter sw = File.AppendText(#"I:\Security Awareness Signed Users\Signed Users.txt"))
{
sw.WriteLine(System.Security.Principal.WindowsIdentity.GetCurrent().Name + "\t" + DateTime.Now.ToString());
}
Environment.Exit(0);
}
This isn't a code writing site; but I was feeling generous. The following class encapsulates storing and retrieving the latest agreement for the current user.
public class AgreementRepository
{
private const string FileLocation = #"I:\Security Awareness Signed Users\Signed Users.txt";
private const char Separator = '\t';
public void AppendAgreementForCurrentUser()
{
string currentUser = GetCurrentUser();
using (StreamWriter sw = File.AppendText(FileLocation))
{
sw.WriteLine($"{currentUser}{Separator}{DateTime.Now:O}");
}
}
public DateTime? GetLastAgreementForCurrentUser()
{
string currentUser = GetCurrentUser();
if (File.Exists(FileLocation) == false)
{
return null;
}
var lastAgreement = File.ReadLines(FileLocation)
.Select(x => x.Split(Separator))
.Where(x => x.Length == 2 && string.Equals(x[0], currentUser, StringComparison.CurrentCultureIgnoreCase))
.Select(x => GetDateTime(x[1]))
.Max();
return lastAgreement;
}
private static DateTime? GetDateTime(string input)
{
DateTime result;
if (DateTime.TryParse(input, out result))
{
return result;
}
return null;
}
private static string GetCurrentUser()
{
return System.Security.Principal.WindowsIdentity.GetCurrent().Name;
}
}
To use this, your form would become...
public partial class frmMain : Form
{
private readonly AgreementRepository _agreementRepository;
public frmMain()
{
_agreementRepository = new AgreementRepository();
InitializeComponent();
txtDateTime.Text = DateTime.Now.ToString();
txtUsername.Text = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
btnClose.Visible = false;
chkAgree.Visible = true;
rtbSecurityAwareness.LoadFile("Security Awareness.rtf");
this.Load += Form1_Load;
}
private void Form1_Load(object sender, EventArgs e)
{
var lastAgreement = _agreementRepository.GetLastAgreementForCurrentUser();
// NOTE: The following condition deals with the fact that lastAgreement could be null
if (lastAgreement > DateTime.Now.AddMonths(-6))
{
Close(); // or Environment.Exit; depends what you need
}
}
private void chkAgree_CheckedChanged(object sender, EventArgs e)
{
btnClose.Visible = chkAgree.Checked; // simplification of your posted code
}
private void btnClose_Click(object sender, EventArgs e)
{
_agreementRepository.AppendAgreementForCurrentUser();
Environment.Exit(0); // Would 'Close()' be enough?
}
Hope this helps

C# - Windows Application - Saving List

I have made a simple TO-DOs program that gets input from a text box then place it in another text box. With tick boxes next to it,
this is all fine except i Cannot save the list eg. the item and if it's finished or not.
Please could anyone help me be able to save this list of items.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TO_DOs
{
public partial class Form1 : Form
{
private bool text1, text2, text3, text4, text5, text6, text7, text8;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (text1 == false)
{
textBox2.Text = textBox1.Text;
}
else if (text2 == false)
{
textBox3.Text = textBox1.Text;
}
else if (text3 == false)
{
textBox4.Text = textBox1.Text;
}
else if (text4 == false)
{
textBox5.Text = textBox1.Text;
}
else if (text5 == false)
{
textBox6.Text = textBox1.Text;
}
else if (text6 == false)
{
textBox7.Text = textBox1.Text;
}
else if (text7 == false)
{
textBox8.Text = textBox1.Text;
}
else if (text8 == false)
{
textBox9.Text = textBox1.Text;
}
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
text1 = true;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void textBox3_TextChanged(object sender, EventArgs e)
{
text2 = true;
}
private void textBox4_TextChanged(object sender, EventArgs e)
{
text3 = true;
}
private void textBox5_TextChanged(object sender, EventArgs e)
{
text4 = true;
}
private void textBox6_TextChanged(object sender, EventArgs e)
{
text5 = true;
}
private void textBox7_TextChanged(object sender, EventArgs e)
{
text6 = true;
}
private void textBox8_TextChanged(object sender, EventArgs e)
{
text7 = true;
}
private void textBox9_TextChanged(object sender, EventArgs e)
{
text8 = true;
}
}
}
I would do it like this:
Create a class to store your values in:
public class ListEntry
{
public string Text { get; set; }
public bool Finished { get; set; }
}
Then I would create 2 Methods:
public List<ListEntry> UI_To_List(); //Create UI from your saved file
public void List_To_UI(List<ListEntry> entries); //Process your UI
Now it's your choice on how to store your list.
You could store it as JSON or XML.
A few recommendations:
I would create a UserControl for your TextBox + CheckBox
Display the 'List of UserControls' in a FlowLayoutPanel
=> then you can process the FlowLayoutPanel.Controls List.
This will make your List dynamically size to an 'unlimited' amount of items.
Short example:
Create a UserControl (Rightclick project for that):
Add these 2 methods to the code of your UserControl (F7 / rightclick => View Code):
public void SetText(string text)
{
//Set the Text of your TextBox in the UserControl:
textBox1.Text = text;
}
public void SetFinished(bool finished)
{
//Set the Checked of your CheckBox in the UserControl:
checkBox1.Checked = finished;
}
In your MainForm add an FlowLayoutPanel (from ToolBox).
Add your Data like this (using class from above):
/// <summary>
///
/// </summary>
/// <param name="entries">You will get them from loading your previously saved file</param>
public void CreateUI(List<ListEntry> entries)
{
foreach (ListEntry entry in entries)
{
//Create new instance of your UserControl
TaskView view = new TaskView();
view.SetFinished(entry.IsFinished);
view.SetText(entry.Text);
//Add that to your UI:
this.flowLayoutPanel1.Controls.Add(view);
}
}
The result will look like this:
I'm not sure what exactly it is that you want to save in a list... but here's just a tip when checking conditions, instead of using if (text1 == false), simply do if (!text1) as this means "is not true" because by default if (text1) will return true.
private void button1_Click(object sender, EventArgs e)
{
if (!text1)
{
textBox2.Text = textBox1.Text;
}
else if (!text2)
{
textBox3.Text = textBox1.Text;
}
// Left out the rest of the else ifs
}
You are casting textboxes wrong. For example when you change textBox4, you gave text3 true.
private void textBox4_TextChanged(object sender, EventArgs e)
{
text3 = true;
}
Then you cast
TextBox4.Text = TextBox1.Text;
It changes TextBox4.Text to TextBox1.Text.
You probably want to save TextBox4.Text here at TextBox1.Text so you sould change all if blocks like that. So you have to give only one "true" function for changed textBox sign and change if blocks
if(text(boolNum))
TextBox1.Text = TextBox(Number).Text;
Just swap them and try like that.
If you want to save another thing by another way. You have to be more spesific.
You can use a CheckedListbox to hold all tot actions.
You can then tick the itemsand for instance in the OK button you include a save action:
foreach(var item in MyCheckedListbox.CheckedItems)
{
Console,WriteLine(item.Text);
}
Lets see the answer from Felix D. He tells you exactly how to create a class and save the items into it. But now you only have a List that will be available as long as your software is running. You still need to save it somewhere on your desktop.
Lucky for you, you got a really simple pattern.
string; boolean
So how about you make it yourself simple? Just create a textfile and write your entries, as example in a csv marked with a ; for every information?
Example:
class Program
{
public class tmpClass
{
public string Text;
public bool tick;
}
public List<tmpClass> tmpList = new List<tmpClass>();
static void Main(string[] args)
{
//Stuff
}
public void WriteToFile()
{
string tmpTextFilePath = #"C:\User\Desktop\SaveText.txt";
using (StreamWriter tmpWriter = new StreamWriter(tmpTextFilePath))
{
string tmpTextToWrite = String.Empty;
for (int i = 0; i < tmpList.Count; i++)
{
tmpClass tmpEntry = tmpList[i];
tmpTextToWrite += tmpEntry.Text + ";" + tmpEntry.tick;
}
tmpWriter.WriteLine(tmpTextToWrite);
}
//Now we wrote a text file to you desktop with all Informations
}
public void ReadFromFile()
{
string tmpTextFilePath = #"C:\User\Desktop\SaveText.txt";
using (StreamReader tmpReader = new StreamReader(tmpTextFilePath))
{
string tmpText = tmpReader.ReadLine();
string tmpInput = String.Empty;
tmpClass tmpClass = new tmpClass();
int i = 0;
foreach (char item in tmpText)
{
if(item.Equals(";".ToCharArray()))
{
if (i == 0)
{
tmpClass.Text = tmpInput;
i = 1;
tmpInput = String.Empty;
}
else
{
if (tmpInput == "True")
tmpClass.tick = true;
else
tmpClass.tick = false;
i = 0;
tmpInput = String.Empty;
tmpList.Add(tmpClass);
}
}
tmpInput += item;
}
}
}
}
This should simply write a txt File to your desktop with your information and read one and save it to your list.

c# how to delete and edit information from selected in listbox?

string Path = #"C:\Users\Alexander\Desktop\Adressbok\Adressbok.txt";
List<string> sökhistorik;
//Lista
List<Person> Personer = new List<Person>();
//instans
Person p1 = new Person();
public Form1()
{
InitializeComponent();
}
private void updateUI()
{
lstBox.DataSource = null;
lstBox.DataSource = Personer;
}
private void btnSpara_Click(object sender, EventArgs e)
{
p1.Namn = tbxNamn.Text;
p1.Gatuadress = tbxGatuadress.Text;
p1.Postnummer = tbxPostnummer.Text;
p1.Postort = tbxPostort.Text;
p1.Telefonnummer = tbxTelefonnummer.Text;
p1.Epost = tbxEpost.Text;
Personer.Add(p1);
updateUI();
SaveToFile();
tbxNamn.Text = "";
tbxGatuadress.Text = "";
tbxPostnummer.Text = "";
tbxPostort.Text = "";
tbxTelefonnummer.Text = "";
tbxEpost.Text = "";
}
I want to edit the selected item from listbox and then edit the information and save it again and then make a delete button and delete the whole information. How do i do it. Im using windows forms c#.
Why don''t you use BindingList instead of List?
BindingList will automatically update your UI based on your source.
Assuming Person has a ToString(),
// Bind BindingList to Listbox
public class Form1 {
BindingList<Person> personer = new BindingList<Person>();
public Form1() {
InitializeComponent();
listBox1.DataSource = personer;
}
// Remove on button click
private void button1_Click(object sender, EventArgs e)
{
if (listBox1.SelectedIndex > -1)
{
//This automatically updates your listBox
personer.RemoveAt(listBox1.SelectedIndex);
}
}
// Update on Button click
private void button2_Click(object sender, EventArgs e)
{
if (listBox1.SelectedIndex > -1)
{
Person p = personer[listBox1.SelectedIndex];
//Update person here
}
}

Categories

Resources