<Border x:Name="CountyResultsDisplay" Background="#77919191" BorderThickness="1" CornerRadius="5"
HorizontalAlignment="Center" VerticalAlignment="Top" Visibility="Collapsed"
Margin="5" Padding="10" BorderBrush="Black">
<Border.Effect>
<DropShadowEffect/>
</Border.Effect>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="15" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock x:Name="DataDisplayTitle" Text="Search Results" Foreground="Black" FontSize="9" Grid.Row="0" FontWeight="Bold" />
<slData:DataGrid x:Name="QueryDetailsDataGrid" Grid.Row="1" Width="Auto" Height="170" AutoGenerateColumns="False" HeadersVisibility="Column" Background="White"
IsReadOnly="True" HorizontalScrollBarVisibility="Hidden"
RowStyle="{StaticResource MyCustomRow}" CanUserSortColumns="True"
SelectionChanged="QueryDetailsDataGrid_SelectionChanged"
LoadingRow="QueryDetailsDataGrid_LoadingRow">
<slData:DataGrid.Columns>
<slData:DataGridTextColumn CanUserSort="True" SortMemberPath="NAME_CNTY" Binding="{Binding Attributes[OBJECTID]}" Header="Rec"/>
<slData:DataGridTextColumn CanUserSort="False" Binding="{Binding Attributes[NAME_CNTY]}" Header="County Name"/>
<slData:DataGridTextColumn CanUserSort="False" Binding="{Binding Attributes[AREA_SQMI]}" Header="Area"/>
<slData:DataGridTextColumn CanUserSort="False" Binding="{Binding Attributes[POP_1990]}" Header="Population 1997"/>
<slData:DataGridTextColumn CanUserSort="False" Binding="{Binding Attributes[POP_2000]}" Header="Population 2000"/>
<slData:DataGridTextColumn CanUserSort="True" SortMemberPath="POP2007" Binding="{Binding Attributes[FIPS_CNTY]}" Header="FIPS"/>
</slData:DataGrid.Columns>
</slData:DataGrid>
</Grid>
</Border>
Query query = new ESRI.ArcGIS.Client.Tasks.Query();
//bind data grid to query results
Binding resultFeaturesBinding = new Binding("LastResult.Features");
resultFeaturesBinding.Source = queryTask;
// Specify fields to return from query according to different layers
if (selectlayerid == 9)
{
DataGrid dg = rectangleselection.QueryDetailsDataGrid;
List <string> Colnames = new List <string> {"OBJECTID", "NAME", "AREA_SQMI", "POP_1990", "POP_2000", "FIPS_CNTY"} ; //header name of the column
dg.Columns.Clear();
if (dg != null)
{
if (Colnames != null && Colnames.Count > 0)
foreach (string col in Colnames)
{
DataGridTextColumn dataGridTextColumn = new DataGridTextColumn();
Binding binder = new Binding();
//you can use the converter if you are binding IDictionary to the datagrid
//binder.Converter = new AttributeRowIndexConverter();
// binder.ConverterParameter = col;
binder.Path = new PropertyPath("Attributes");
dataGridTextColumn.Header = col;
binder.Mode = BindingMode.OneWay;
dataGridTextColumn.Binding = binder;
dg.Columns.Add(dataGridTextColumn);
}
}
rectangleselection.QueryDetailsDataGrid.SetBinding(DataGrid.ItemsSourceProperty, resultFeaturesBinding);
query.OutFields.AddRange(new string[] { "OBJECTID", "NAME_CNTY", "AREA_SQMI", "POP_1990", "POP_2000", "FIPS_CNTY" });
}
You have to bind to a specific attribbute not to the whole dictionary (e.g. in XAML Binding="{Binding Attributes[NAME_CNTY]}" ).
So instead of 'binder.Path = new PropertyPath("Attributes");', try with : binder.Path = new PropertyPath("Attributes[" + col + "]");
Can I bind the visible attribute fields in each layer without specify the attribute names in codes. I mean I can set the attribute field of the layer to be visible or invisible in arcmap (please see the attached picture).
If I want the query task returns the results from these visible attribute fields and I don't specify these attribute names in my code. Is there a way to do such thing?
So I am wondering if there is a way to read the visible columns automatically and only bind the visible columns and perform spatial query based on them.
string fieldname = featureSet.FieldAliases.ElementAt(i).ToString(); MessageBox.Show(fieldname);
private void SelectQueryTask_ExecuteCompleted(object sender, ESRI.ArcGIS.Client.Tasks.QueryEventArgs args)
{
FeatureSet featureSet = args.FeatureSet;
if (featureSet != null && featureSet.Features.Count > 0)
{
switch (Convert.ToInt16(args.UserState.ToString()))
{
case 9: //specify the layerid
{
DataGrid dg = rectangleselection.QueryDetailsDataGrid;
dg.Columns.Clear();
List<string> fields = new List<string>();
MessageBox.Show(featureSet.FieldAliases.Count().ToString());
foreach (var item in featureSet.FieldAliases)
{
DataGridTextColumn dataGridTextColumn = new DataGridTextColumn();
Binding binder = new Binding();
fields.Add(item.Value);
binder.Path = new PropertyPath("Attributes[" + item.Value + "]");
dataGridTextColumn.Header = item.Value;
binder.Mode = BindingMode.OneWay;
dataGridTextColumn.Binding = binder;
dg.Columns.Add(dataGridTextColumn);
}
rectangleselection.ParentLayoutRoot = InfoCanvas;
rectangleselection.ResultsDisplay.Visibility = System.Windows.Visibility.Visible;
rectangleselection.Show();
rectangleselection.thisPass(this); //pass current reference to rectangleselection
break;
}
I check the field alias from arcmap, for example, the field NAME_CNTY's field alias is NAME_CNTY, but when I use this line to display it, it shows [NAME_CNTY, NAME_CNTY]
Code:
string fieldname = featureSet.FieldAliases.ElementAt(i).ToString();MessageBox.Show(fieldname);
I don't know why it shows the duplicated name
binder.Path = new PropertyPath("Attributes[" + item.Value + "]");
The second question which is more confusing is that since I want to generate the column automatically I set the AutoGenerateColumns="True" for the datagrid according to Yamunadevi's advice
DataGrid dg = rectangleselection.QueryDetailsDataGrid;
List<string> fields = new List<string>();
dg.Columns.Clear();
//generate the index column
DataGridTextColumn dataGridTextColumnRec = new DataGridTextColumn();
Binding Recbinder = new Binding();
//Recbinder.Path = new PropertyPath();
dataGridTextColumnRec.Header = "Rec";
Recbinder.Mode = BindingMode.OneWay;
dataGridTextColumnRec.Binding = Recbinder;
dg.Columns.Add(dataGridTextColumnRec);
foreach (var item in featureSet.FieldAliases)
{
DataGridTextColumn dataGridTextColumn = new DataGridTextColumn();
Binding binder = new Binding();
fields.Add(item.Value); //FieldAliases is a Dictionary, the field name being the key and the field alias being the value.
binder.Path = new PropertyPath("Attributes[" + item.Key + "]");
dataGridTextColumn.Header = item.Value;
binder.Mode = BindingMode.OneWay;
dataGridTextColumn.Binding = binder;
dg.Columns.Add(dataGridTextColumn);
}
So if I change the field alias to something more common, e.g. Name (instead of the current NAME_CNTY), I should be able to use it by item.Value as the header of the column right?
I also try to add a new column as the index of the records, which should be the first column. I attach a scrrenshot hereAttachment 6498. So I generate a column before the fieldaliases loop. But I dont know how to give the Recbinder.Path since it is not an attribute of the featureset.
int rec = 0; foreach(var feature in featureSet.Features) feature.Attributes["Rec"] = ++rec;
Binding Recbinder = new Binding("Attributes[Rec]"); dataGridTextColumnRec.Header = "Rec"; Recbinder.Mode = BindingMode.OneWay; dataGridTextColumnRec.Binding = Recbinder; dg.Columns.Add(dataGridTextColumnRec);