I am not sure whether I can generate these datagrids in code-behind, instead of in xaml which is more rigid
var myDataGrid = new DataGrid
{
Height = 170,
AutoGenerateColumns = false,
IsReadOnly =true,
HorizontalScrollBarVisibility= ScrollBarVisibility.Hidden,
HeadersVisibility = DataGridHeadersVisibility.Column,
Background = new SolidColorBrush(Colors.White),
RowStyle = (Style)LayoutRoot.Resources["MyCustomRow"],
CanUserSortColumns = true
};
myDataGrid.SelectionChanged += QueryDetailsDataGrid_SelectionChanged;
myDataGrid.LoadingRow += QueryDetailsDataGrid_LoadingRow;
myPanel.Children.Add(myDataGrid);
dataGridTextColumn.Header = _lastIdentifyResult.ElementAt(i).Feature.Attributes.ElementAt(j).Key.ToString();
IdentifyPage idtask = new IdentifyPage();
private void IdentifyTask_ExecuteCompleted(object sender, IdentifyEventArgs args)
{
if (args.IdentifyResults.Count == 0)
{
MessageBox.Show("No features found at click location.");
}
else if (args.IdentifyResults.Count > 0)
{
_lastIdentifyResult = args.IdentifyResults;
idtask.IdentifyPanel.Children.Clear(); //clear the identify results datagrids
for (int i = 0; i < _lastIdentifyResult.Count; i++)
{
TextBlock layernameTextBlc = new TextBlock();
layernameTextBlc.Text = _lastIdentifyResult.ElementAt(i).LayerName; //add the layer's name
TextBlock space = new TextBlock();
space.Height = 10; //add a space between each datagrid
var idDataGrid = new DataGrid
{
Height = 100,
AutoGenerateColumns = false,
IsReadOnly = true,
HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden,
HeadersVisibility = DataGridHeadersVisibility.Column,
Background = new SolidColorBrush(Colors.White),
RowStyle = (Style)LayoutRoot.Resources["MyCustomRow"],
CanUserSortColumns = true
};
List<string> fields = new List<string>();
idDataGrid.Columns.Clear();
//generate the columns
for (int j = 0; j < _lastIdentifyResult.ElementAt(i).Feature.Attributes.Count() - 1; j++)
{
DataGridTextColumn dataGridTextColumn = new DataGridTextColumn();
Binding binder = new Binding();
fields.Add(_lastIdentifyResult.ElementAt(i).Feature.Attributes.ElementAt(j).Value.ToString());
binder.Path = new PropertyPath("Attributes[" + _lastIdentifyResult.ElementAt(i).Feature.Attributes.ElementAt(j).Key + "]");
dataGridTextColumn.Header = _lastIdentifyResult.ElementAt(i).Feature.Attributes.ElementAt(j).Key.ToString();
binder.Mode = BindingMode.OneWay;
dataGridTextColumn.Binding = binder;
idDataGrid.Columns.Add(dataGridTextColumn);
}
idtask.IdentifyPanel.Children.Add(space);
idtask.IdentifyPanel.Children.Add(layernameTextBlc);
idtask.IdentifyPanel.Children.Add(idDataGrid);
}
idtask.ParentLayoutRoot = InfoCanvas;
//idtask.idDataGrid.Visibility = System.Windows.Visibility.Visible;
idtask.Show();
//idtask.thisPass(this); //pass current reference to rectangleselection
}
}
The columns' name are correct by this line, since the key is the field alias.
The second question is that for some reasons the datagrids didn't show the field 'OBJECTID', but they showed the field 'Shape'.
List<string> fields = new List<string>();
idDataGrid.Columns.Clear();
//generate the columns
for (int j = 0; j < _lastIdentifyResult.ElementAt(i).Feature.Attributes.Count(); j++)
{
DataGridTextColumn dataGridTextColumn = new DataGridTextColumn();
Binding binder = new Binding();
fields.Add(_lastIdentifyResult.ElementAt(i).Feature.Attributes.ElementAt(j).Value.ToString());
//binder.Path = new PropertyPath("Attributes[" + _lastIdentifyResult.ElementAt(i).Feature.Attributes.ElementAt(j).Key + "]");
binder.Path = new PropertyPath(_lastIdentifyResult.ElementAt(i).Feature.Attributes.ElementAt(j).Value);
dataGridTextColumn.Header = _lastIdentifyResult.ElementAt(i).Feature.Attributes.ElementAt(j).Key.ToString();
binder.Mode = BindingMode.OneWay;
dataGridTextColumn.Binding = binder;
idDataGrid.Columns.Add(dataGridTextColumn);
}
Regard to the field name or the field alias, please see the first screenshot. The datagrid and the property are from the same layer. For field 'POP_1990', its field alias is Population - 1990, which shows in the datagrid...
I used "dataGridTextColumn.Header = _lastIdentifyResult.ElementAt(i).Feature.Attributes.ElementAt(j).Key.ToString()" to get the column name...so that's why I guess Key is the field alias.
//binder.Path = new PropertyPath("Attributes[" + _lastIdentifyResult.ElementAt(i).Feature.Attributes.ElementAt(j).Key + "]");
binder.Path = new PropertyPath(_lastIdentifyResult.ElementAt(i).Feature.Attributes.ElementAt(j).Value);
else if (args.IdentifyResults.Count > 0)
{
_lastIdentifyResult = args.IdentifyResults;
Graphic[,] identifyList = new Graphic[34,30]; //declear a 2D graphic array to store the results, row: layerid (we have 34 layers in the map service), column: graphic
int [] gCount = new int [34]; //tract the number of graphics in each layer
idtask.IdentifyPanel.Children.Clear(); //clear the identify results datagrid
for (int i = 0; i < _lastIdentifyResult.Count; i++) //traversal each identify result
{
int layerIndex = _lastIdentifyResult.ElementAt(i).LayerId; //layerid of the result
gCount[layerIndex]++; //the number of the graphics in this layer plus one
Graphic identifyGraphic = _lastIdentifyResult.ElementAt(i).Feature; //graphic of the result
identifyList[layerIndex, (gCount[layerIndex]-1)] = identifyGraphic; //store the layerid and the graphic to the 2D graphic array
}
for (int i = 0; i < 34; i++ )
{
if (gCount > 0) //if the current layer has identify results, generate datagrid
{
List<Graphic> gList = new List<Graphic>(); //declar a new graphic list to store the graphics from the same layer
for (int k = 0; k < gCount; k++) //add the graphics to the graphic list
{
gList.Add(identifyList[i, k]);
}
TextBlock layernameTextBlc = new TextBlock();
layernameTextBlc.Text = dynamicServiceLayer.Layers.ElementAt(i).Name; //store the layer's name
TextBlock space = new TextBlock(); //a blank textblock used as a row space
space.Height = 10;
var idDataGrid = new DataGrid //generate a datagrid
{
Height = (gCount == 1? 50: 125),
AutoGenerateColumns = false,
IsReadOnly = true,
HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
VerticalScrollBarVisibility = ScrollBarVisibility.Visible,
HeadersVisibility = DataGridHeadersVisibility.Column,
Background = new SolidColorBrush(Colors.White),
RowStyle = (Style)LayoutRoot.Resources["MyCustomRow"],
CanUserSortColumns = true
};
idDataGrid.Columns.Clear();
//initialize a new attribute used for record index
int rec = 0;
foreach (var graphic in gList)
graphic.Attributes["Rec"] = ++rec;
//generate the first column for record index
DataGridTextColumn dataGridTextColumnRec = new DataGridTextColumn();
Binding Recbinder = new Binding();
Recbinder.Path = new PropertyPath("Attributes[Rec]");
dataGridTextColumnRec.Header = "Rec";
Recbinder.Mode = BindingMode.OneWay;
dataGridTextColumnRec.Binding = Recbinder;
idDataGrid.Columns.Add(dataGridTextColumnRec);
//generate the columns
for (int j = 0; j < identifyList[i, 0].Attributes.Count();j++ )
{
if (identifyList[i, 0].Attributes.ElementAt(j).Key == "Shape" || identifyList[i, 0].Attributes.ElementAt(j).Key == "Shape.area" ||
identifyList[i, 0].Attributes.ElementAt(j).Key == "Shape.len")
break;
DataGridTextColumn dataGridTextColumn = new DataGridTextColumn();
Binding binder = new Binding();
//binder.Path = new PropertyPath("Attributes[" + _lastIdentifyResult.ElementAt(i).Feature.Attributes.ElementAt(j).Key + "]");
binder.Path = new PropertyPath("Attributes[" + identifyList[i, 0].Attributes.ElementAt(j).Key + "]");
//dataGridTextColumn.Header = _lastIdentifyResult.ElementAt(i).Feature.Attributes.ElementAt(j).Key.ToString();
dataGridTextColumn.Header = identifyList[i, 0].Attributes.ElementAt(j).Key.ToString(); //header is the field alias
binder.Mode = BindingMode.OneWay;
dataGridTextColumn.Binding = binder;
idDataGrid.Columns.Add(dataGridTextColumn);
}
idDataGrid.ItemsSource = gList; //initialize the ItemsSource of the datagrid with that list of graphics
//idDataGrid.ItemsSource = new List<Graphic> { identifyList[i, 0] };
idtask.IdentifyPanel.Children.Add(space); //add the blank textblock
idtask.IdentifyPanel.Children.Add(layernameTextBlc); //add the layer's name
idtask.IdentifyPanel.Children.Add(idDataGrid); //add the datagrid
}
}
idtask.ParentLayoutRoot = InfoCanvas;
idtask.Show();
<Border x:Name="ResourceTabBorder" Margin="5,0,5,0" Visibility="Collapsed" BorderBrush="#FFFFFFCC">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="Visible Layers" Foreground="Black" FontWeight="Bold" Grid.Row="0"/>
<ListBox x:Name="ResourceListBox" FontSize="12" Background="#FFFFFFCC" BorderBrush="#FFFFFFCC" Grid.Row="1">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Margin="2" FontSize="9"
Name="ResourceCheckBox"
Content="{Binding Name}"
IsChecked="{Binding DefaultVisibility}"
Tag="{Binding ID}"
ClickMode="Press"
Click="ResourceCheckBox_Click"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Border>
<slData:DataGrid x:Name="BufferDataGrid" Grid.Row="1" Width="Auto" Height="170" AutoGenerateColumns="False" HeadersVisibility="Column" Background="White" IsReadOnly="True" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Auto" CanUserSortColumns="True"/>
var idDataGrid = new DataGrid //generate a datagrid
{
Height = (gCount == 1? 70: 125), //if there is only one graphic in the layer, height = 70, otherwise, height = 125
AutoGenerateColumns = false,
IsReadOnly = true,
HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
VerticalScrollBarVisibility = ScrollBarVisibility.Visible,
HeadersVisibility = DataGridHeadersVisibility.Column,
Background = new SolidColorBrush(Colors.White),
CanUserSortColumns = true
};