아래 내 창 (전체 화면)에 대한 전체 클래스를 연결합니다. 나는 내가 쟁점/염려/문제라고 생각하는 것을 논평 할 것이고, 후에 나는 내 의견을 목록 순서대로 설명 할 것이다. 가장 유용한 대답은 코드를 참조로 사용하여 나열된 질문에 대답하는 사람들입니다. 메인 윈도우 cs와 RowContainer 클래스 (간단한 관리 클래스)를 제공 할 것입니다. 여기 같은 행에서 행 및 모든 컨트롤 제거
내가 모든 행은 내가 행을 제거 할 때까지 이동해야하는 경우 나 확실하지 않다 간단하기 때문에이 방법 RemoveFromRowList을 표시public partial class MainWindow : Window
{
public static DebugWindow debugWindow;
public static MainWindow mainWindow;
public static Dispatcher mainWindowDispacter;
private Object locker = new Object();
public ConnectionHandle ConnectionHandler;
public RowContainer[] RowContents;
public MainWindow()
{
InitializeComponent();
mainWindow = this;
mainWindowDispacter = this.Dispatcher;
}
public RowContainer RowExists(Client c)
{
if (RowContents == null)
return null;
foreach (RowContainer r in RowContents)
{
if (r.GetClient().getUID().Equals(c.getUID()))
return r;
}
return null;
}
// ----------------1 --------------------
public void RemoveFromRowList(RowContainer r)
{
List<RowContainer> l = new List<RowContainer>();
List<int> usedList = new List<int>();
int deleteRowNumber = r.rowNumber;
foreach (RowContainer rr in RowContents)
{
if (!r.Equals(rr))
{
if (rr.rowNumber > deleteRowNumber)
rr.rowNumber--;
l.Add(rr);
}
}
RowContents = l.ToArray();
}
//----------------------- 2 -------------------
public void AddToRowList(RowContainer r)
{
if (RowContents == null)
{
r.rowNumber = 1;
RowContents = new RowContainer[] { r };
return;
}
List<RowContainer> l = new List<RowContainer>();
List<int> usedList = new List<int>();
foreach (RowContainer rr in RowContents)
{
l.Add(rr);
usedList.Add(rr.rowNumber);
}
Console.WriteLine(usedList.ToString());
int? firstAvailable = Enumerable.Range(1, int.MaxValue)
.Except(usedList)
.FirstOrDefault();
r.rowNumber = (int)firstAvailable;
l.Add(r);
RowContents = l.ToArray();
}
private void onDebugLogClick(object sender, RoutedEventArgs e)
{
if (debugWindow == null)
{
debugWindow = new DebugWindow();
debugWindow.Show();
}
else
{
if (debugWindow.IsVisible)
{
debugWindow.Hide();
}
else
debugWindow.Visibility = Visibility.Visible;
}
}
public BitmapImage ToImage(byte[] array)
{
using (var ms = new System.IO.MemoryStream(array))
{
var image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = ms;
image.EndInit();
return image;
}
}
// type 0 - image, 1 - status, 2 - OS, 3 - Idle, 4 - bitaccount
public void UpdateRowContainer(RowContainer r, int type)
{
switch (type)
{
case 0:
BitmapImage image = ToImage(r.Image);
System.Windows.Controls.Image uiImage = (System.Windows.Controls.Image)MyGrid.Children.Cast<UIElement>().First(e => Grid.GetRow(e) == r.rowNumber & Grid.GetColumn(e) == 0);
if (uiImage == null)
{
}
else
{
uiImage.Source = image;
}
break;
case 2:
Label OsLabel = (System.Windows.Controls.Label)MyGrid.Children.Cast<UIElement>().First(e => Grid.GetRow(e) == r.rowNumber & Grid.GetColumn(e) == 5);
OsLabel.Content = r.Os;
break;
case 3:
Label idleLabel = (System.Windows.Controls.Label)MyGrid.Children.Cast<UIElement>().First(e => Grid.GetRow(e) == r.rowNumber & Grid.GetColumn(e) == 3);
idleLabel.Content = r.idle;
break;
}
}
// --------------------------- 3----------------------
public void CreateClientRowContainer(Client c, byte[] imageBytes)
{
RowContainer newContainer = new RowContainer(c);
BitmapImage image = ToImage(imageBytes);
newContainer.Image = imageBytes;
Label cLabel = new Label();
Label osLabel = new Label();
Label stateLabel = new Label();
Label bitAccountLabel = new Label();
Label idleTimeLabel = new Label();
osLabel.Content = "N/A";
stateLabel.Content = "N/A";
bitAccountLabel.Content = "N/A";
idleTimeLabel.Content = "N/A";
cLabel.Content = c.getClientIp();
cLabel.SetValue(Grid.ColumnProperty, 1);
stateLabel.SetValue(Grid.ColumnProperty, 2);
idleTimeLabel.SetValue(Grid.ColumnProperty, 3);
bitAccountLabel.SetValue(Grid.ColumnProperty, 4);
osLabel.SetValue(Grid.ColumnProperty, 5);
int rowCount = this.MyGrid.RowDefinitions.Count;
this.MyGrid.RowDefinitions.Add(new RowDefinition());
Style style = this.FindResource("LabelTemplate") as Style;
Style style2 = this.FindResource("OSTemplate") as Style;
cLabel.Style = style;
stateLabel.Style = style;
bitAccountLabel.Style = style;
idleTimeLabel.Style = style;
osLabel.Style = style2;
cLabel.SetValue(Grid.RowProperty, rowCount);
bitAccountLabel.SetValue(Grid.RowProperty, rowCount);
stateLabel.SetValue(Grid.RowProperty, rowCount);
idleTimeLabel.SetValue(Grid.RowProperty, rowCount);
osLabel.SetValue(Grid.RowProperty, rowCount);
System.Windows.Controls.Image imgIcon = new System.Windows.Controls.Image();
imgIcon.Height = 150;
imgIcon.HorizontalAlignment = HorizontalAlignment.Center;
imgIcon.VerticalAlignment = VerticalAlignment.Top;
imgIcon.Source = image;
MyGrid.Children.Add(cLabel);
MyGrid.Children.Add(idleTimeLabel);
MyGrid.Children.Add(stateLabel);
MyGrid.Children.Add(bitAccountLabel);
MyGrid.Children.Add(osLabel);
ConnectionHandle.SendRequestInformation(c, 3);
imgIcon.SetValue(Grid.ColumnProperty, 0);
imgIcon.SetValue(Grid.RowProperty, rowCount);
MyGrid.Children.Add(imgIcon);
AddToRowList(newContainer);
}
// -------------------- 4 ---------------------
public void RemoveClientGrid(Client c)
{
RowContainer con = RowExists(c);
if (con == null)
return;
if (MyGrid.RowDefinitions.Count < con.rowNumber)
{
RemoveFromRowList(con);
return;
}
Console.WriteLine("Removing row: " + con.rowNumber);
Console.WriteLine("Total rows: " + MyGrid.RowDefinitions.Count);
RowDefinitionCollection defs = MyGrid.RowDefinitions;
foreach (UIElement control in MyGrid.Children)
{
if (Grid.GetRow(control) == con.rowNumber)
{
MyGrid.Children.Remove(control);
}
}
defs.RemoveAt(con.rowNumber);
RemoveFromRowList(con);
}
protected override void OnClosing(CancelEventArgs e)
{
if (debugWindow != null)
debugWindow.Close();
Environment.Exit(Environment.ExitCode);
base.OnClosing(e);
}
private void onServerStartClick(object sender, RoutedEventArgs e)
{
if (ConnectionHandler == null)
{
ConnectionHandler = new ConnectionHandle();
}
else
{
MessageBox.Show("Server Has Already Started!");
}
}
private Client GetRowClient(int row)
{
foreach(RowContainer r in RowContents) {
if (r.rowNumber == row)
return r.client;
}
return null;
}
private void onRefreshMenuClick(object sender, RoutedEventArgs e)
{
MenuItem mi = sender as MenuItem;
if (mi != null)
{
ContextMenu cm = mi.CommandParameter as ContextMenu;
if (cm != null)
{
Grid g = cm.PlacementTarget as Grid;
if (g != null)
{
var p = Mouse.GetPosition(g);
int row = 0;
int col = 0;
double accumulatedHeight = 0.0;
double accumulatedWidth = 0.0;
// calc row mouse was over
foreach (var rowDefinition in g.RowDefinitions)
{
accumulatedHeight += rowDefinition.ActualHeight;
if (accumulatedHeight >= p.Y)
break;
row++;
}
Client c = GetRowClient(row);
if (c != null)
{
ConnectionHandle.SendRequestInformation(c, 1);
ConnectionHandle.SendRequestInformation(c, 4);
}
else
if (debugWindow != null)
debugWindow.LogTextBox.AppendText("Unable to find client!");
}
}
}
}
private void onDisconnectClicked(object sender, RoutedEventArgs e)
{
MenuItem mi = sender as MenuItem;
if (mi != null)
{
ContextMenu cm = mi.CommandParameter as ContextMenu;
if (cm != null)
{
Grid g = cm.PlacementTarget as Grid;
if (g != null)
{
var p = Mouse.GetPosition(g);
int row = 0;
int col = 0;
double accumulatedHeight = 0.0;
double accumulatedWidth = 0.0;
// calc row mouse was over
foreach (var rowDefinition in g.RowDefinitions)
{
accumulatedHeight += rowDefinition.ActualHeight;
if (accumulatedHeight >= p.Y)
break;
row++;
}
Client c = GetRowClient(row);
if (c != null)
{
// ----- RemoveFromClientPool is basically RemoveClientGrid(c) seen above.
ClientHandle.RemoveFromClientPool(c, "Server Requested");
}
else
if (debugWindow != null)
debugWindow.LogTextBox.AppendText("Unable to find client!");
}
}
}
}
}
1) ... GUI를의 사진입니다 . 행 번호는 RowContainer 클래스에 지정되어 있습니다.
2) 거의 동일한 우려 사항 ... 정확히 무슨 일이 발생했는지 모르겠다. 방금 행 번호를 삽입했다. 5 클라이언트가 있고 3 대째 wpf 그리드에 연결이 끊어진 경우 연결되는 다음 클라이언트가 3 번 행을 가져옵니다? 어리석게 들리니, 4시에 3시와 5시에 4시 될 것입니다.
3) 그리드에 대한 새로운 행을 생성하는 방법입니다. 그것은 못생긴지만 내 유일한 관심사가 작동하는 것 같습니다 정말 행 번호 0 내 기본 텍스트를 찍은 번호입니다. 그래서 카운트가 맞을 것 같은 새로운 줄에서 나를 시작할 것입니다. 이후 첫 번째 클라이언트는 해당 카운트 = 1 (단지 내가 전에 가지고있는 기본 행을 계산).
4) 글쎄, 이것이 내 주요 문제라고 생각한다. 모든 컨트롤과 행 자체를 제거합니다. 그것은 순간에 System.InvalidOperationException을 던지는 것처럼 보입니다. 하지만 내 행 번호 매기기가 꺼져 있다고 확신합니다.
---- 전체적인 문제 : a) 행이 남을 때 행 번호는 어떻게됩니까? (새 클라이언트가 오면 마지막 지점이 생기고 거기에 있던 다른 모든 클라이언트가 한 줄 위로 이동합니까?) b) wpf의 Grid에서 행 내의 모든 컨트롤을 포함하여 효율적으로 행을 제거하려면 어떻게해야합니까?
내 RowContainer 클래스에 문제가 있다고 생각하지 않습니다. 모든 작업을 수행 할 수 있기 때문에 atm이 더러운 것입니다. 그러나 그것은 분명히 어떤 실제적인 실수를 던지지 않을 것입니다.
public class RowContainer
{
public byte[] Image { get; set; }
public String state;
public String ip;
public String Os {get; set;}
public String bitacc;
public String idle {get; set;}
public Client client;
public int rowNumber { get; set; }
public RowContainer(Client c)
{
this.ip = c.getClientIp();
this.client = c;
}
public void SetIdleTime(String time)
{
this.idle = time;
}
public void SetState(String st)
{
this.state = st;
}
public void SetBCAccount(String bc){
this.bitacc = bc;
}
public String GetIp()
{
return this.ip;
}
public String GetBitAccount()
{
return this.bitacc;
}
public Client GetClient()
{
return this.client;
}
public String GetIdleTime()
{
return this.idle;
}
public String GetState()
{
return this.GetState();
}
}