I've been trying to implement minimax algorithm in my C# chess engine for a week now and it makes legal moves but not meaningful moves. I cannot find the error, hopefully someone can spot it. I have tried to isolate the problem by testing each method and they all seem to work correctly except minimax.
public enum Piece
{
Empty, Pawn_W, Pawn_B, Knight_W, Knight_B,
Bishop_W, Bishop_B, Rook_W, Rook_B,
Queen_W, Queen_B, King_W, King_B
}
public bool IsPieceWhite(Piece piece)
{
if (piece == Piece.Pawn_W || piece == Piece.Knight_W ||
piece == Piece.Bishop_W || piece == Piece.Rook_W ||
piece == Piece.Queen_W || piece == Piece.King_W)
return true;
else return false;
}
public bool IsPieceBlack(Piece piece)
{
if (piece == Piece.Pawn_B || piece == Piece.Knight_B ||
piece == Piece.Bishop_B || piece == Piece.Rook_B ||
piece == Piece.Queen_B || piece == Piece.King_B)
return true;
else return false;
}
public int GetPieceWorth(Piece piece)
{
if (piece == Piece.Pawn_W || piece == Piece.Pawn_B)
return 1;
if (piece == Piece.Knight_W || piece == Piece.Knight_B)
return 3;
if (piece == Piece.Bishop_W || piece == Piece.Bishop_B)
return 3;
if (piece == Piece.Rook_W || piece == Piece.Rook_B)
return 5;
if (piece == Piece.Queen_W || piece == Piece.Queen_B)
return 9;
if (piece == Piece.King_W || piece == Piece.King_B)
return 9999999;
return 0;
}
Piece[,] CurrentBoard = GetStartingBoard();
Piece[,] bestMove;
public int depthB = 3;
public double minimax(Piece[,] board, int depth, bool maximizingPlayer)
{
if (depth == 0)
{
double result = EvaluatePosition(board, maximizingPlayer);
return result;
}
if (maximizingPlayer)
{
double best = Double.MinValue;
double value = Double.MinValue;
foreach (var move in GenerateMoves(board, maximizingPlayer))
{
Piece[,] clonedMove = CloneBoard(move);
value = Math.Max(value, minimax(clonedMove, depth - 1, false));
if (depth == depthB && value >= best)
{
best = value;
bestMove = clonedMove;
}
}
return value;
}
else
{
double best = Double.MaxValue;
double value = Double.MaxValue;
foreach (var move in GenerateMoves(board, maximizingPlayer))
{
Piece[,] clonedMove = CloneBoard(move);
value = Math.Min(value, minimax(clonedMove, depth - 1, true));
if (depth == depthB && value <= best)
{
best = value;
bestMove = clonedMove;
}
}
return value;
}
}
public Piece[,] CloneBoard(Piece[,] boardPos)
{
Piece[,] copy = boardPos.Clone() as Piece[,];
return copy;
}
public double EvaluatePosition(Piece[,] boardPos, bool ForWhite)
{
double eval = 0;
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
if (boardPos[i, j] != Piece.Empty)
{
if (IsPieceWhite(boardPos[i, j]))
{
eval += GetPieceWorth(boardPos[i, j]);
}
else if (IsPieceBlack(boardPos[i, j]))
{
eval -= GetPieceWorth(boardPos[i, j]);
}
}
}
}
if (ForWhite)
return eval;
else
return eval * -1;
}
//a-h,0-7
//Piece[,] board = new Piece[8, 8];
public static Piece[,] GetStartingBoard()
{
Piece[,] board = new Piece[8, 8];
for (int i = 0; i < 8; i++)
{
//initiate pawns
board[1, i] = Piece.Pawn_W;
board[6, i] = Piece.Pawn_B;
}
//white pieces
board[0, 0] = Piece.Rook_W;
board[0, 1] = Piece.Knight_W;
board[0, 2] = Piece.Bishop_W;
board[0, 3] = Piece.Queen_W;
board[0, 4] = Piece.King_W;
board[0, 5] = Piece.Bishop_W;
board[0, 6] = Piece.Knight_W;
board[0, 7] = Piece.Rook_W;
//black pieces
board[7, 0] = Piece.Rook_B;
board[7, 1] = Piece.Knight_B;
board[7, 2] = Piece.Bishop_B;
board[7, 3] = Piece.Queen_B;
board[7, 4] = Piece.King_B;
board[7, 5] = Piece.Bishop_B;
board[7, 6] = Piece.Knight_B;
board[7, 7] = Piece.Rook_B;
//test
//board[1, 4] = Piece.Pawn_B;
//board[6, 2] = Piece.Pawn_W;
return board;
}
I have uploaded a short clip of the engine playing against itself, to show the wierd moves: https://www.youtube.com/watch?v=A0HVgXYSciY
Finally was able to make the minimax function work. Thanks for all the help!
Working method:
public int minimax(Piece[,] board, int depth, bool maximizingPlayer, bool WhiteToPlay)
{
if (depth == 0)
{
int result = EvaluatePosition(board, WhiteToPlay);
return result;
}
var moves = GenerateMoves(board, WhiteToPlay);
if (maximizingPlayer)
{
int value = int.MinValue;
foreach (var move in moves)
{
int minmaxResult = minimax(move, depth - 1, false, !WhiteToPlay);
value = Math.Max(value, minmaxResult);
if (depth == depthB)
{
moveScores.Add(move, minmaxResult);
}
}
return value;
}
else
{
int value = int.MaxValue;
foreach (var move in moves)
{
int minmaxResult = minimax(move, depth - 1, true, !WhiteToPlay);
value = Math.Min(value, minmaxResult);
if (depth == depthB)
{
moveScores.Add(move, minmaxResult);
}
}
return value;
}
}
I have searched the similar games on forum and google but i could not find exactly.
I am making a puzzle game. and user can get point if the nodes (horizontal sticks) are same color then he can get.
when they are in same direction it says colors matched but in generated node whenever i rotate the sticks it says also same.
Can you take a look? and tell me how to fix. Also if you have better idea about this matching I will be appreciated.
---------
void Update()
{
if (Input.GetMouseButtonDown(0))
{
clickTime = Time.time;
rayhit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero, Mathf.Infinity, selectableObjLayerMask);
}
else if (Input.GetMouseButtonUp(0))
{
if (rayhit)
{
if (Time.time - clickTime < .2f)
{
Node node = rayhit.transform.GetComponent<Node>();
if (node != null)
{
for (int i = 0; i < node.sticks.Count; i++)
{
Vector3 newAngles = new Vector3(0, 0, (node.sticks[i].transform.localEulerAngles.z - 45));
newAngles.z = newAngles.z < 0 ? newAngles.z + 180 : newAngles.z;
newAngles.z = newAngles.z >180 ? newAngles.z - 180 : newAngles.z;
node.sticks[i].transform.localEulerAngles = newAngles;
node.sticks[i].degree = (int)newAngles.z;
//******** HERE IS COLOR MATCHING*******
if (node.transform.parent.name=="Node1" && node.sticks[i].degree == 90)
{
colorMatch[1] = node.sticks[i].color;
Debug.Log("COLOR 1___"+ colorMatch[1]);
//Debug.Log(colorMatch1);
}
if (node.transform.parent.name == "Node2" && node.sticks[i].degree == 90)
{
colorMatch[2] = node.sticks[i].color;
Debug.Log("COLOR 2___" + colorMatch[2]);
}
if (node.transform.parent.name == "Node3" && node.sticks[i].degree == 90)
{
colorMatch[3] = node.sticks[i].color;
Debug.Log("COLOR 3___" + colorMatch[3]);
//if (colorMatch[1] == colorMatch[2] && colorMatch[2] == colorMatch[3])
//{
// Debug.Log("COLORS MATCHED : " + colorMatch[1]);
//}
}
if (colorMatch[1]==colorMatch[2] && colorMatch[2]==colorMatch[3])
{
Debug.Log("COLOR MATCHED");
}
}
}
}
else
{
Node currNode = rayhit.transform.GetComponent<Node>();
if(currNode.isMoved == false)
{
smallestId = 0;
smallestDistance = 999;
for (int i = 0; i < nodes.Length; i++)
{
float distance = Vector2.Distance(rayhit.transform.position, nodes[i].transform.position);
if (smallestDistance > distance)
{
smallestDistance = distance;
smallestId = i;
}
}
rayhit.transform.position = nodes[smallestId].transform.position;
if (rayhit.transform.parent != nodes[smallestId].transform)
{
if (nodes[smallestId].transform.childCount > 0 && nodes[smallestId].transform != rayhit.transform.parent)
{
if (currNode != null)
{
for (int i = 0; i < currNode.sticks.Count; i++)
{
nodes[smallestId].transform.GetChild(0).GetComponent<Node>().sticks.Add(currNode.sticks[i]);
currNode.sticks[i].transform.SetParent(nodes[smallestId].transform.GetChild(0));
}
Destroy(rayhit.transform.gameObject);
}
}
else
{
if (currNode != null)
{
currNode.isMoved = true;
}
rayhit.transform.SetParent(nodes[smallestId].transform);
}
}
}
}
}
rayhit = new RaycastHit2D();
}
else if (Input.GetMouseButton(0))
{
if(rayhit.transform != null)
{
Node currNode = rayhit.transform.GetComponent<Node>();
if(currNode != null)
if (currNode.isMoved == false)
{
if (Time.time - clickTime >= 0.2f)
{
Vector2 newPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
rayhit.transform.position = newPos;
}
}
}
}
}
if (node.transform.parent.name=="Node1" && node.sticks[i].degree == 90)
{
colorMatch[1] = node.sticks[i].color;
Debug.Log("COLOR 1___"+ colorMatch[1]);
//Debug.Log(colorMatch1);
}
if (node.transform.parent.name == "Node2" && node.sticks[i].degree == 90)
{
colorMatch[2] = node.sticks[i].color;
Debug.Log("COLOR 2___" + colorMatch[2]);
}
if (node.transform.parent.name == "Node3" && node.sticks[i].degree == 90)
{
colorMatch[3] = node.sticks[i].color;
Debug.Log("COLOR 3___" + colorMatch[3]);
if (colorMatch[1] == colorMatch[2] && colorMatch[2] == colorMatch[3])
{
Debug.Log("COLORS MATCHED : " + colorMatch[1]);
}
}
Here is working code. but how i can destroy the matched sticks?
I have strings like:
1) Cookie:ystat_tw_ss376223=9_16940400_234398;
2) Cookie:zynga_toolbar_fb_uid=1018132522
3) GET /2009/visuels/Metaboli_120x600_UK.gif HTTP/1.1
4) GET /2010/07/15/ipad-3hk-smv-price-hk/ HTTP/1.1
1 ad 2 have common substtring{cookie:}
3 and 4 have common substtring{GET /20, HTTP/1.1}
I want to find all common substrings that have the length more than three characters(contain space character) between 2 strings.(like 1 and 2)
i want to code in c#. i have a program but it has some problems.
Could anyone help me?
public static string[] MyMCS2(string a, string b)
{
string[] st = new string[100];
// List<string> st = new List<string>();
List<char> f = new List<char>();
int ctr = 0;
char[] str1 = a.ToCharArray();
char[] str2 = b.ToCharArray();
int m = 0;
int n = 0;
while (m < str1.Length)
{
for (n = 0; n < str2.Length; n++)
{
if (m < str1.Length)
{
if (str1[m] == str2[n])
{
if ((m > 1) && (n > 1) &&(str1[m - 1] == str2[n - 1]) && (str1[m - 2] == str2[n - 2]))
{
//f[m]= str1[m];
f.Add(str1[m]);
char[] ff = f.ToArray();
string aaa = new string(ff);
if (aaa.Length >= 3)
{
st[ctr] = aaa + "()";
//st.Add(aaa);
ctr++;
}
kk = m;
m++;
}
else if ((n == 0) ||(n == 1))
{
f.Add(str1[m]);
kk = m;
m++;
}
else
f.Clear();
}
//else if ((str1[m] == str2[n]) && (m == str1.Length - 1) && (n == str2.Length - 1))
//{
// f.Add(str1[m]);
// char[] ff = f.ToArray();
// string aaa = new string(ff);
// if (aaa.Length >= 3)
// {
// st[ctr] = aaa;
// ctr++;
// }
// // m++;
//}
else if ((str1[m] != str2[n]) && (n == (str2.Length - 1)))
{
m++;
}
else if ((m > 1) && (n > 1) && (str1[m] != str2[n]) && (str1[m - 1] == str2[n - 1]) && (str1[m - 2] == str2[n - 2]) && (str1[m - 3] == str2[n - 3]))
{
//
char[] ff = f.ToArray();
string aaa = new string(ff);
if (aaa.Length >= 3)
{
st[ctr] = aaa + "()" ;
//st.Add(aaa);
ctr++;
f.Clear();
}
//f.Clear();
//for (int h = 0; h < ff.Length; h++)
//{
// f[h] = '\0';
//}
}
else if (str1[m] != str2[n])
continue;
}
}
}
//int gb = st.Length;
return st;
}
This is an exact matching problem not a substring. You can solve it with aho-corasick algorithm. Use the first string and compute a finite state machine. Then process the search string. You can extend the aho-corasick algorithm to use a wildcard and search also for substrings. You can try this animated example: http://blog.ivank.net/aho-corasick-algorithm-in-as3.html
I am using a data table to store some data. After the for loop check the length of the data table, the data table clears itself. There is no data in it. Can you advise why is it so ? This is part part of a report that is using the DevExpress reporting engine to create the reports.
DataTable ResultList = new DataTable();
ResultList.Columns.Add("range");
ResultList.Columns.Add("bpfrom");
ResultList.Columns.Add("bpto");
ResultList.Columns.Add("qualMemb");
ResultList.Columns.Add("qualTurn");
ResultList.Columns.Add("qualTurnPercent");
ResultList.Columns.Add("grMemb");
ResultList.Columns.Add("grTurn");
ResultList.Columns.Add("grTurnPercent");
ResultList.Columns.Add("totalamt");
ResultList.Columns.Add("giftlevel");
string[] fromrangelist = fromrange.Split(',');
string[] torangelist = torange.Split(',');
int j;
if (fromrange == "")
{
DataRow dr = ResultList.NewRow();
dr["range"] = 1;
dr["bpfrom"] = 0;
dr["bpto"] = 100000000; //biggest value
dr["giftlevel"] = "ALL";
ResultList.Rows.Add(dr);
}
else
{
for (j = 0; j < fromrangelist.Length; j++)
{
DataRow dr = ResultList.NewRow();
dr["range"] = j + 1;
dr["bpfrom"] = Convert.ToDecimal(fromrangelist[j]);
dr["bpto"] = Convert.ToDecimal(torangelist[j]);
dr["giftlevel"] = "level:" + (j + 1).ToString() + "(" + fromrangelist[j] + "-" + torangelist[j] + ")";
ResultList.Rows.Add(dr);
}
}
//Get ALL Total spend
decimal TotalSpend = Math.Round((from table1 in context.mmsspddtls
where table1.mmsspdcpcd.Equals(cpcd) && table1.mmsspdbrcd.Equals(brcd)
&& table1.mmsspdtxdt >= fromtxdate && table1.mmsspdtxdt <= totxdate
&& (table1.mmsspdtxty.Equals(null) || table1.mmsspdtxty.Equals("") || table1.mmsspdtxty.Equals("PS") || table1.mmsspdtxty.Equals("PE") || table1.mmsspdtxty.Equals("PR"))
&& (table1.mmsspdplna.Equals('1') || table1.mmsspdplna.Equals('5') || table1.mmsspdplna.Equals('P') || table1.mmsspdplna.Equals('T') || table1.mmsspdplna.Equals('A') || table1.mmsspdplna.Equals('L'))
&& !table1.mmsspdstfg.Equals('V')
select new
{
totalamt = table1.mmsspdpram
}).Sum(s => s.totalamt), 2);
for (int i = 0; i < ResultList.Rows.Count; i++)
{
decimal fromvalue = Convert.ToDecimal(ResultList.Rows[i]["bpfrom"]);
decimal tovalue = Convert.ToDecimal(ResultList.Rows[i]["bpto"]);
ResultList.Rows[i]["totalamt"] = TotalSpend;
//Member Query that match the range
var MemberQuery = (from table1 in context.mmscrdlogs
where table1.mmscdlcpcd.Equals(cpcd) && table1.mmscdlbrcd.Equals(brcd)
&& table1.mmscdlstst.Equals('N') && table1.mmscdlbpis >= fromvalue && table1.mmscdlbpis <= tovalue
&& table1.mmscdleddt >= fromexpiredate && table1.mmscdleddt <= toexpiredate
select new
{
spendfr = fromvalue,
spendto = tovalue,
membercode = table1.mmscdlmbcd
}).Distinct();
//Count of member in the range
ResultList.Rows[i]["qualMemb"] = MemberQuery.Count();
//member total spend in the range
decimal qualTurn = 0;
var qualQuery = (from table1 in context.mmsspddtls
from table2 in MemberQuery.Where(s => s.membercode == table1.mmsspdmbcd)
where table1.mmsspdcpcd.Equals(cpcd) && table1.mmsspdbrcd.Equals(brcd)
&& table1.mmsspdtxdt >= fromtxdate && table1.mmsspdtxdt <= totxdate
&& (table1.mmsspdtxty.Equals(null) || table1.mmsspdtxty.Equals("") || table1.mmsspdtxty.Equals("PS") || table1.mmsspdtxty.Equals("PE") || table1.mmsspdtxty.Equals("PR"))
&& (table1.mmsspdplna.Equals('1') || table1.mmsspdplna.Equals('5') || table1.mmsspdplna.Equals('P') || table1.mmsspdplna.Equals('T') || table1.mmsspdplna.Equals('A') || table1.mmsspdplna.Equals('L'))
&& !table1.mmsspdstfg.Equals('V')
select new
{
totalamt = table1.mmsspdpram
});
if(qualQuery.Count() > 0)
{
qualTurn = Math.Round(qualQuery.Sum(s => s.totalamt), 2);
}
ResultList.Rows[i]["qualTurn"] = qualTurn;
//member total spend% with total in the range
if (qualTurn == 0)
ResultList.Rows[i]["qualTurnPercent"] = 0;
else
ResultList.Rows[i]["qualTurnPercent"] = Math.Round((qualTurn / TotalSpend) * 100, 2);
var MemberQueryGR = (from table1 in context.mmsspddtls
from table2 in context.pxppludpxes.Where(s => s.pxppdxcpcd.Equals(table1.mmsspdcpcd) && s.pxppdxbrcd.Equals(table1.mmsspdbrcd) && s.pxppdxplcd.Equals(table1.mmsspdplcd))
from table3 in context.mmssyspars.Where(s => s.mmssypcpcd.Equals(table1.mmsspdcpcd) && s.mmssypbrcd.Equals(table1.mmsspdbrcd))
where table1.mmsspdcpcd.Equals(cpcd) && table1.mmsspdbrcd.Equals(brcd)
&& table2.pxppdxpx01 / (table3.mmssypbpmt / table3.mmssyppont) >= fromvalue
&& table2.pxppdxpx01 / (table3.mmssypbpmt / table3.mmssyppont) <= tovalue
&& table1.mmsspdtxty.Equals("GR") && table1.mmsspdplna.Equals('2')
&& table1.mmsspdtxdt >= fromtxdate && table1.mmsspdtxdt <= totxdate
select new
{
spendfr = fromvalue,
spendto = tovalue,
membercode = table1.mmsspdmbcd
}).Distinct();
//Count of GR member in the range
ResultList.Rows[i]["grMemb"] = MemberQueryGR.Count();
//GR member total spend in the range
decimal grTurn = 0;
if (MemberQueryGR.Count() > 0)
{
var grQuery = (from table1 in context.mmsspddtls
from table2 in MemberQueryGR.Where(s => s.membercode == table1.mmsspdmbcd)
where table1.mmsspdcpcd.Equals(cpcd) && table1.mmsspdbrcd.Equals(brcd)
&& table1.mmsspdtxdt >= fromtxdate && table1.mmsspdtxdt <= totxdate
&& (table1.mmsspdtxty.Equals(null) || table1.mmsspdtxty.Equals("") || table1.mmsspdtxty.Equals("PS") || table1.mmsspdtxty.Equals("PE") || table1.mmsspdtxty.Equals("PR"))
&& (table1.mmsspdplna.Equals('1') || table1.mmsspdplna.Equals('5') || table1.mmsspdplna.Equals('P') || table1.mmsspdplna.Equals('T') || table1.mmsspdplna.Equals('A') || table1.mmsspdplna.Equals('L'))
&& !table1.mmsspdstfg.Equals('V')
select new
{
totalamt = table1.mmsspdpram
});
if(grQuery.Count() > 0)
{
grTurn = Math.Round(grQuery.Sum(s => s.totalamt), 2);
}
}
ResultList.Rows[i]["grTurn"] = grTurn;
//member total spend% with total in the range
if (grTurn == 0)
ResultList.Rows[i]["grTurnPercent"] = 0;
else
ResultList.Rows[i]["grTurnPercent"] = Math.Round((grTurn / TotalSpend) * 100, 2);
}
DataSource = ResultList;
}
Please advise. Thanks
I want to make an application in WPF same as windows application. When i use treeview event in wpf i did not find any event similar to treeview_NodeMouseClick of WIndows Application.
//Windows Application Code
private void tv_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (e.Node != null)
{
GetAllchield(e.Node, e.Node.Level);
}
}
// GetAllchield
public void GetAllchield(TreeNode clickednode, int indexDepth)
{
if (clickednode.Nodes.Count > 0 && !clickednode.IsExpanded)
{
clickednode.Collapse();
return;
}
string[] FullPath = clickednode.FullPath.Split('\\');
string rootnode = FullPath[0].ToString();
//get all market for root event type
int eventTypeID = DictionaryAllActiveEventTypes[rootnode];
string[] allMarkets = GetAllMarketForEventID(eventTypeID);
//selecting unque chield node and populating in tree
for (int i = 0; i < allMarkets.Length; i++)
{
if (allMarkets[i].Contains(clickednode.Text))
{
string[] marketDetails = allMarkets[i].Split('~');
int marketID = Convert.ToInt32(marketDetails[0]);
string MarketName = marketDetails[1].ToString();
string MarketStatus = marketDetails[3].ToString();
string EventHeirarchy = marketDetails[6].ToString();
string Menupath = marketDetails[5].ToString();
string[] Arrmenupath = Menupath.Trim(':').Split('\\');
string chieldText = "";
if (indexDepth == 0)
{
if (rootnode == "Cricket" || rootnode == "Tennis" || rootnode == "Golf" || rootnode == "Rugby")
{
if (Arrmenupath[2].Contains("Group") && Arrmenupath[2].Length == 7)
{
if ((indexDepth + 3) <= Arrmenupath.Length - 1)
{
chieldText = Arrmenupath[indexDepth + 3].ToString();
}
}
else
{
if ((indexDepth + 2) <= Arrmenupath.Length - 1)
chieldText = Arrmenupath[indexDepth + 2].ToString();
}
}
else
if ((indexDepth + 2) <= Arrmenupath.Length - 1)
chieldText = Arrmenupath[indexDepth + 2].ToString();
}
else
{
if (Arrmenupath[Arrmenupath.Length - 1] == clickednode.Text)
chieldText = MarketName;
else
{
if (allMarkets[i].Contains(clickednode.Text) && allMarkets[i].Contains(clickednode.Parent.Text) && allMarkets[i].Contains(rootnode))
{
if (rootnode == "Cricket" || rootnode == "Tennis" || rootnode == "Golf" || rootnode == "Rugby")
{
if (Arrmenupath[2].Contains("Group") && Arrmenupath[2].Length == 7)
{
if ((indexDepth + 3) <= Arrmenupath.Length - 1)
{
chieldText = Arrmenupath[indexDepth + 3].ToString();
}
}
else
{
if ((indexDepth + 2) <= Arrmenupath.Length - 1)
chieldText = Arrmenupath[indexDepth + 2].ToString();
}
}
else
if ((indexDepth + 2) <= Arrmenupath.Length - 1)
chieldText = Arrmenupath[indexDepth + 2].ToString();
}
}
}
//check whether node is already added
//if (chieldText.Contains("MiWay"))
//{ }
if (!string.IsNullOrEmpty(chieldText))
{
if (clickednode.Nodes.Count >= 1)
{
bool doesNodeAlreadyExist = false;
foreach (TreeNode node in clickednode.Nodes)
{
if (node.Text == chieldText)
{
doesNodeAlreadyExist = true;
break;
}
}
if (!doesNodeAlreadyExist)
{
clickednode.Nodes.Add(chieldText);
}
}
else
{
clickednode.Nodes.Add(chieldText);
}
}
}
}
clickednode.Expand();
}
I want to use same as in WPF. Please help me or if you get it.
You can use MouseLeftButtonDown and check sender argument or use SelectedItemChanged