Mailing Labels

3465
13
04-05-2011 05:21 AM
JayKappy
Occasional Contributor
Has anyone out there done mailing labels through Silverlight?
Anyone maybe have an example?

I have the spatial query workign that is returning results to a datagrid fine...now just need to get them to format in IE or something to print to an Avery type mailing label format...

Thanks
0 Kudos
13 Replies
PatrickBrooke
New Contributor II
My site does it. What it does is output address data to .cvs, then the user does the mail merge from that. I though about going right to Word, but decided against that for many reasons.

http://gis.modestogov.com

The way you access it in our site is through our buffer tool, on the tool bar.

Is that what you are looking for?
0 Kudos
JayKappy
Occasional Contributor
Yea something like that woudl be great....like I said Ido a sptial query that selects records from a PArcel feature class and binds them to a data grid....I just need to take the selected records and export them to a CSV file....I just have to figure out how to get that list to a CSV file....
Any help with that code would be great...
0 Kudos
BrentHoskisson
Occasional Contributor III
To get the selected items from a DataGrid in C#:

IList<MyClass> listClass = (IList<MyClass>)myDataGrid.SelectedItems;


After that you just loop through the list and create your CSV file.  There is no function to automatically do it.  You can google "C# Create CSV" to get many examples.

Good Luck
0 Kudos
JayKappy
Occasional Contributor
I convert to VB and get this
BUT with an error on MyClass not defined...just not sure what the MyClass is refering too

Second...am I grabbing selected records from the list? I want them all, not the selected

'Dim listClass As IList(Of [MyClass]) = DirectCast(QueryDetailsDataGrid.SelectedItems, IList(Of [MyClass]))


One other question not really related Patrick Brooke
when you do a select in your app the identify results window comes up...
how did you create the vertical line seperating the results from the data? I know stupid question but new to this...
0 Kudos
BrentHoskisson
Occasional Contributor III
Sorry, it seems I was trying to send you through an extra step.  You can just loop on the SelectedItems property.  Each item can be cast back to the class that is the original ItemsSource of your DataGrid.

If you want all the records you can cast the ItemsSource back to the ObservableCollection it came from and loop through that.
0 Kudos
JayKappy
Occasional Contributor
Bit confused here.....I am doign this to add the features to a graphics layer in the map (highlighted)

I assume that it would be in this For Each loop that I would build some sort of list?  not really sure how....

       If featureSet IsNot Nothing AndAlso featureSet.Features.Count > 0 Then
            For Each feature As Graphic In featureSet.Features
                feature.Symbol = TryCast(LayoutRoot.Resources("ResultsFillSymbol"), FillSymbol)
                graphicsLayer.Graphics.Insert(0, feature)
            Next feature
            ResultsDisplay.Visibility = Visibility.Visible
        End If
0 Kudos
PatrickBrooke
New Contributor II
I will share my code from this process for logic reasons, know it is custom to my environment. I am hope the logic makes sense at least. I am really happy with the way mine works, it took we a few days to nail it down, but well worth it.


First, the QueryTask_ExecuteCompleted that has the parcels that fall within the buffer the users creates in a previous step. Also, in here is where I separate the initial selection that the buffer was generated from (blue parcels), and the ones added to the selection by the buffer (red parcels).  _bufferitems is a custom class I made just for this task. It made it much easier for me.

 private void QueryTask_ExecuteCompleted(object sender, QueryEventArgs args)
        {

            //Reset Selected (blue) graphics
            identifySelect.ClearGraphics();
            //Add all blue (Selected) graphics to graphics layer
            foreach (DataItem x in _bufferSelectedItems)
            {
                ESRI.ArcGIS.Client.Graphic graphic = new ESRI.ArcGIS.Client.Graphic()
                {
                    Geometry = x.geodata,
                   
                    Symbol = GlobalVariables.theMainPage.LayoutRoot.Resources["SelectedFillSymbol"] as FillSymbol
                };
                identifySelect.Graphics.Add(graphic);
               
            } 

            //Reset Results (red) graphics
            identifyResults.ClearGraphics();

            // "_bufferList" will hold all if the results from the parcel query and display them in the child window when called
            _bufferList = new List<_bufferItems>();


            //Add all red (Results) graphics to graphics layer
            //And add each result to the buffer csv list
            foreach (Graphic feature in args.FeatureSet)
            {

                string StreetNum = "";
                string StreetDir = "";
                string Street = "";
                string StreetType = "";
                

                feature.Symbol = GlobalVariables.theMainPage.LayoutRoot.Resources["ResultFillSymbol"] as FillSymbol;

                bool uniqueGraphic = true;

                //If graphic exists in Selection Graphics Layer (_bufferSelectedItems), do not add to Results Graphics Layer
                //This allows the user to see the initial buffer selection versus the parcels returned from the buffer parcel query
                foreach (DataItem x in _bufferSelectedItems)
                {

                    if (x.Data[StringID.APN].ToString() == feature.Attributes[StringID.APN].ToString())
                    {
                        uniqueGraphic = false;
                    }
                }
                if (uniqueGraphic)
                {
                    identifyResults.Graphics.Add(feature);
                }

                //Create a new buffer item
                _bufferItems rptItemsSitus = new _bufferItems();
                _bufferItems rptItemsOwner = new _bufferItems();

                //Gather individual fields to create full address
                //This "if" statement returns true if the user is looking for situs or both addresses
                if (GlobalVariables.theBufferChoice.rdoBoth.IsChecked == true || GlobalVariables.theBufferChoice.rdoSitus.IsChecked == true)
                {
                    if (feature.Attributes[StringID.csvStNum] != null)
                    {
                        StreetNum = feature.Attributes[StringID.csvStNum].ToString().Trim();
                    }

                    if (feature.Attributes[StringID.csvStDir] != null)
                    {
                        StreetDir = feature.Attributes[StringID.csvStDir].ToString().Trim();
                    }

                    if (feature.Attributes[StringID.csvSt] != null)
                    {
                        Street = feature.Attributes[StringID.csvSt].ToString().Trim();
                    }

                    if (feature.Attributes[StringID.csvStType] != null)
                    {
                        StreetType = feature.Attributes[StringID.csvStType].ToString().Trim();
                    }
                    //Use "Occupant" for external users
                    rptItemsSitus.Name = "Occupant";

                    //Concatinate address
                    rptItemsSitus.Address = StreetNum + " " + StreetDir + " " + Street + " " + StreetType;

                    if (feature.Attributes[StringID.csvCity] != null)
                    {
                        rptItemsSitus.City = feature.Attributes[StringID.csvCity].ToString();
                    }
                    if (feature.Attributes[StringID.csvState] != null)
                    {
                        rptItemsSitus.State = feature.Attributes[StringID.csvState].ToString();
                    }
                    if (feature.Attributes[StringID.csvZip] != null)
                    {
                        rptItemsSitus.Zip = feature.Attributes[StringID.csvZip].ToString();
                    }
                    _bufferList.Add(rptItemsSitus);
                }

                //This "if" statement returns true if the user is looking for owner or both addresses
                if (GlobalVariables.theBufferChoice.rdoBoth.IsChecked == true || GlobalVariables.theBufferChoice.rdoOwner.IsChecked == true)
                {
                    if (feature.Attributes[StringID.csvMailAddress] != null)
                    {
                        Street = feature.Attributes[StringID.csvMailAddress].ToString().Trim();
                    }
                                       
                    if (feature.Attributes[StringID.csvFirstLast] != null)
                    {
                        rptItemsOwner.Name = feature.Attributes[StringID.csvFirstLast].ToString().Trim();
                    }
   
                    //Concatinate address
                    rptItemsOwner.Address = Street;

                    if (feature.Attributes[StringID.csvMailCity] != null)
                    {
                        rptItemsOwner.City = feature.Attributes[StringID.csvMailCity].ToString();
                    }
                    if (feature.Attributes[StringID.csvMailState] != null)
                    {
                        rptItemsOwner.State = feature.Attributes[StringID.csvMailState].ToString();
                    }
                    if (feature.Attributes[StringID.csvMailZip] != null)
                    {
                        rptItemsOwner.Zip = feature.Attributes[StringID.csvMailZip].ToString();
                    }
                    _bufferList.Add(rptItemsOwner);
                }

            }


            //Fill datagrid with results
            dgReport.ItemsSource = _bufferList;

            //lets the BufferChoice control know that the report has run
            GlobalVariables.theSideMenu.buffercontrol.makeChoiceOpenFalse();
        }


Then, take the _bufferlist created in the querytask and generate it to a .csv

private void SaveButton_Click(object sender, RoutedEventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog()
            {
                DefaultExt = "csv",
                Filter = "Comma Separated Values (*.csv)|",
                FilterIndex = 1

            };

            int bufferCount = _bufferList.Count;

            sfd.ShowDialog();

            System.IO.Stream stream = sfd.OpenFile();

            StreamWriter sw = new StreamWriter(stream);

            sw.Write("\"Name\",\"Address\",\"City\",\"State\",\"Zip\"\r\n");

            for (int i = 0; i <= bufferCount - 1; i++)
            {
                sw.Write("\"" + _bufferList.Name + "\",\"" + _bufferList.Address + "\",\""
                + _bufferList.City + "\",\"" + _bufferList.State + "\",\"" + _bufferList.Zip + "\" \r\n");
            }
            sw.Close();
            stream.Close();
        }
0 Kudos
PatrickBrooke
New Contributor II
Hi Jay,

Just saw your question about the line. It is hard to remember some times because I wrote most of this site 1.5 years ago. The line is just a line...it is just placed in by code. If you use expression blend, it should be easier to do in your environment.

<!-- This is the Line thats visible between the Identify Results list and the Tab Control-->
      <Line X1="178" X2="178" Y1="0" Y2="365" Stroke="Black" StrokeThickness="1" Grid.ColumnSpan="2" />
0 Kudos
JayKappy
Occasional Contributor
Hey thanks for the code example.....bit more than I expected....but going to try and tackle it...

I understand the buffer and code needed to get the results...
You code then builds a List from the results.
The user then clicks a button that allows then to save the list created to a csv file.
I am getting confused when you say you created a New Class...


  1. Question....what is the class you created doing?....I am not understanding that part...

  2.      _bufferitems is custom class I made just for this task. It made it much easier for me.
  3. Wondering how that effects the code?  Are you calling the class? Are you sending the results to the new class?  Is there processing going on in the new class...

  4. It seems the private void SaveButton_Click button is clicked after the selection has occured and the list has been created...


            // "_bufferList" will hold all if the results from the parcel query and display them in the child window when called
            _bufferList = new List<_bufferItems>();
0 Kudos