Preserving ListView state

Xaml Serialization to the rescue.

The following sample code will persist the current Listview state to disk and restore it the next time the control is loaded.

[code:c#]

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        Loaded="OnLoaded"
        >
    <Grid>
        <Border x:Name="bdr">
        <ListView x:Name="lvTest" Initialized="lvInit">
            <ListView.View>
                <GridView>
                    <GridViewColumn Width="140" Header="Column 1" />
                    <GridViewColumn Width="140" Header="Column 2" />
                    <GridViewColumn Width="140" Header="Column 3" />
                </GridView>
            </ListView.View>
        </ListView>
        </Border>
    </Grid>
</Window>
 

[/code]

Code behind 

[code:c#]

using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void lvInit(object sender, EventArgs e)
        {
            GridView gv = lvTest.View as GridView;
            gv.Columns.CollectionChanged += (s, gvE) =>
            {
                if (gvE.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Move)
                {
                    SaveState();
                }
            };

        }


        private void SaveState()
        {
            string lvXaml = XamlWriter.Save(lvTest);
            using (var s = new StreamWriter(@"c:\temp\lv.xaml"))
            {
                s.Write(lvXaml);
            }
        }
              
        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            ListView li = null;
            if (File.Exists(@"c:\temp\lv.xaml"))
                bdr.Child = (ListView)XamlReader.Load(File.OpenRead(@"c:\temp\lv.xaml"));           
        }

       
    }
}

[/code]

Linq to Xlsx

A sample how to read a Excel 2007/2010 using Open XML SDK V2

(forgive the bad syntax highlighting)

 

[code:c#]

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml.Packaging;

namespace ConsoleApplicationLinqToXlsx
{
    class Program
    {
        static void Main(string[] args)
        {
            //Declare variables to hold refernces to Excel objects.
            Workbook workBook;
            SharedStringTable sharedStrings;
            IEnumerable<Sheet> workSheets;
            WorksheetPart custSheet;
            WorksheetPart orderSheet;

            //Declare helper variables.
            string custID;
            string orderID;
            List<Customer> customers;
            List<Order> orders;

            //Open the Excel workbook.
            using (SpreadsheetDocument document =
              SpreadsheetDocument.Open(@"d:\Temp\ConsoleApplicationLinqToXlsx\TestOpenXMl.xlsx ", true))
            {
                //References to the workbook and Shared String Table.
                workBook = document.WorkbookPart.Workbook;
                workSheets = workBook.Descendants<Sheet>();
                sharedStrings =
                  document.WorkbookPart.SharedStringTablePart.SharedStringTable;

                //Reference to Excel Worksheet with Customer data.
                custID =
                  workSheets.First(s => s.Name == @"Customer").Id;
                custSheet =
                  (WorksheetPart)document.WorkbookPart.GetPartById(custID);

                //Load customer data to business object.
                customers =
                  Customer.LoadCustomers(custSheet.Worksheet, sharedStrings);

                //Reference to Excel worksheet with order data.
                orderID =
                  workSheets.First(sheet => sheet.Name == @"Order").Id;
                orderSheet =
                  (WorksheetPart)document.WorkbookPart.GetPartById(orderID);

                //Load order data to business object.
                orders =
                  Order.LoadOrders(orderSheet.Worksheet, sharedStrings);

                //List all customers to the console.
                //Write header information to the console.
                Console.WriteLine("All Customers");
                Console.WriteLine("{0, -15} {1, -15} {2, -5}",
                  "Customer", "City", "State");

                //LINQ Query for all customers.
                IEnumerable<Customer> allCustomers =
                    from customer in customers
                    select customer;

                //Execute query and write customer information to the console.
                foreach (Customer c in allCustomers)
                {
                    Console.WriteLine("{0, -15} {1, -15} {2, -5}",
                      c.Name, c.City, c.State);
                }
                Console.WriteLine();
                Console.WriteLine();


                //Write all orders over $100 to the console.
                //Write header information to the console.
                Console.WriteLine("All Orders over $100");
                Console.WriteLine("{0, -15} {1, -10} {2, 10} {3, -5}",
                  "Customer", "Date", "Amount", "Status");

                //LINQ Query for all orders over $100.
                //Join used to display customer information for the order.
                var highOrders =
                  from customer in customers
                  join order in orders on customer.Name equals order.Customer
                  where order.Amount > 100.00
                  select new
                  {
                      customer.Name,
                      order.Date,
                      order.Amount,
                      order.Status
                  };

                //Execute query and write information to the console.
                foreach (var result in highOrders)
                {
                    Console.WriteLine("{0, -15} {1, -10} {2, 10} {3, -5}",
                      result.Name, result.Date.ToShortDateString(),
                      result.Amount, result.Status);
                }
                Console.WriteLine();
                Console.WriteLine();


                //Report on customer orders by status.
                //Write header information to  the console.
                Console.WriteLine("Customer Orders by Status");

                //LINQ Query for summarizing customer order information by status.
                //There are two LINQ queries. 
                //Internal query is used to group orders together by status and
                //calculates the total order amount and number of orders.
                //External query is used to join Customer information.
                var sumoforders =
                  from customer in customers
                  select new
                  {
                      customer.Name,
                      statusTotals =
                          from order in orders
                          where order.Customer == customer.Name
                          group order.Amount by order.Status into statusGroup
                          select new
                          {
                              status = statusGroup.Key,
                              orderAmount = statusGroup.Sum(),
                              orderCount = statusGroup.Count()
                          }
                  };

                //Execute query and write information to the console.
                foreach (var customer in sumoforders)
                {
                    //Write Customer name to the console.
                    Console.WriteLine("-{0}-", customer.Name);
                    foreach (var x in customer.statusTotals)
                    {
                        Console.WriteLine("  {0, -10}: {2,2} orders totaling {1, 7}",
                          x.status, x.orderAmount, x.orderCount);
                    }
                    Console.WriteLine();
                }

                //Keep the console window open.
                Console.Read();
            }
        }

        /// <summary>
        /// Used to store customer information for analysis.
        /// </summary>
        public class Customer
        {
            //Properties.
            public string Name { get; set; }
            public string City { get; set; }
            public string State { get; set; }

            /// <summary>
            /// Helper method for creating a list of customers
            /// from an Excel worksheet.
            /// </summary>
            public static List<Customer> LoadCustomers(Worksheet worksheet,
              SharedStringTable sharedString)
            {
                //Initialize the customer list.
                List<Customer> result = new List<Customer>();

                //LINQ query to skip first row with column names.
                IEnumerable<Row> dataRows =
                  from row in worksheet.Descendants<Row>()
                  where row.RowIndex > 1
                  select row;

                foreach (Row row in dataRows)
                {
                    //LINQ query to return the row's cell values.
                    //Where clause filters out any cells that do not contain a value.
                    //Select returns the value of a cell unless the cell contains
                    //  a Shared String.
                    //If the cell contains a Shared String, its value will be a
                    //  reference id which will be used to look up the value in the
                    //  Shared String table.
                    IEnumerable<String> textValues =
                      from cell in row.Descendants<Cell>()
                      where cell.CellValue != null
                      select
                        (cell.DataType != null
                          && cell.DataType.HasValue
                          && cell.DataType == CellValues.SharedString
                        ? sharedString.ChildElements[
                          int.Parse(cell.CellValue.InnerText)].InnerText
                        : cell.CellValue.InnerText)
                      ;

                    //Check to verify the row contained data.
                    if (textValues.Count() > 0)
                    {
                        //Create a customer and add it to the list.
                        var textArray = textValues.ToArray();
                        Customer customer = new Customer();
                        customer.Name = textArray[0];
                        customer.City = textArray[1];
                        customer.State = textArray[2];
                        result.Add(customer);
                    }
                    else
                    {
                        //If no cells, then you have reached the end of the table.
                        break;
                    }
                }

                //Return populated list of customers.
                return result;
            }
        }

        /// <summary>
        /// Used to store order information for analysis.
        /// </summary>
        public class Order
        {
            //Properties.
            public string Number { get; set; }
            public DateTime Date { get; set; }
            public string Customer { get; set; }
            public Double Amount { get; set; }
            public string Status { get; set; }

            /// <summary>
            /// Helper method for creating a list of orders
            /// from an Excel worksheet.
            /// </summary>
            public static List<Order> LoadOrders(Worksheet worksheet,
              SharedStringTable sharedString)
            {
                //Initialize order list.
                List<Order> result = new List<Order>();

                //LINQ query to skip first row with column names.
                IEnumerable<Row> dataRows =
                  from row in worksheet.Descendants<Row>()
                  where row.RowIndex > 1
                  select row;

                foreach (Row row in dataRows)
                {
                    //LINQ query to return the row's cell values.
                    //Where clause filters out any cells that do not contain a value.
                    //Select returns cell's value unless the cell contains
                    //  a shared string.
                    //If the cell contains a shared string its value will be a
                    //  reference id which will be used to look up the value in the
                    //  shared string table.
                    IEnumerable<String> textValues =
                      from cell in row.Descendants<Cell>()
                      where cell.CellValue != null
                      select
                        (cell.DataType != null
                          && cell.DataType.HasValue
                          && cell.DataType == CellValues.SharedString
                        ? sharedString.ChildElements[
                          int.Parse(cell.CellValue.InnerText)].InnerText
                        : cell.CellValue.InnerText)
                      ;

                    //Check to verify the row contains data.
                    if (textValues.Count() > 0)
                    {
                        //Create an Order and add it to the list.
                        var textArray = textValues.ToArray();
                        Order order = new Order();
                        order.Number = textArray[0];
                        order.Date = new DateTime(1900, 1, 1).AddDays(
                          Double.Parse(textArray[1]) - 2);
                        order.Customer = textArray[2];
                        order.Amount = Double.Parse(textArray[3]);
                        order.Status = textArray[4];
                        result.Add(order);
                    }
                    else
                    {
                        //If no cells, then you have reached the end of the table.
                        break;
                    }
                }

                //Return populated list of orders.
                return result;
            }
        }

    }
}

[/code]

Type Equivalence Embedded Interop Types

 

Beginning with the .NET Framework version 4, the common language runtime supports embedding type information for COM types directly into managed assemblies, instead of requiring the managed assemblies to obtain type information for COM types from interop assemblies. Because the embedded type information includes only the types and members that are actually used by a managed assembly, two managed assemblies might have very different views of the same COM type. Each managed assembly has a different Type object to represent its view of the COM type. The common language runtime supports type equivalence between these different views for interfaces, structures, enumerations, and delegates.

Type equivalence means that a COM object that is passed from one managed assembly to another can be cast to the appropriate managed type in the receiving assembly.

NoteNote

Type equivalence and embedded interop types simplify the deployment of applications and add-ins that use COM components, because it is not necessary to deploy interop assemblies with the applications. Developers of shared COM components still have to create primary interop assemblies (PIAs) if they want their components to be used by earlier versions of the .NET Framework.

Type Equivalence

Equivalence of COM types is supported for interfaces, structures, enumerations, and delegates. COM types qualify as equivalent if all of the following are true:

  • The types are both interfaces, or both structures, or both enumerations, or both delegates.

  • The types have the same identity, as described in the next section.

  • Both types are eligible for type equivalence, as described in the Marking COM Types for Type Equivalence section.

Type Identity

Two types are determined to have the same identity when their scopes and identities match, in other words, if they each have the TypeIdentifierAttribute attribute, and the two attributes have matching Scope and Identifier properties. The comparison for Scope is case-insensitive.

If a type does not have the TypeIdentifierAttribute attribute, or if it has a TypeIdentifierAttribute attribute that does not specify scope and identifier, the type can still be considered for equivalence as follows:

Marking COM Types for Type Equivalence

You can mark a type as eligible for type equivalence in two ways:

.NET Concurrency

Optimistic Concurrency

In a multiuser environment, there are two models for updating data in a database: optimistic concurrency, and pessimistic concurrency. The DataSet object is designed to encourage the use of optimistic concurrency for long-running activities such as when you are remoting data and when users are interacting with data.

Pessimistic concurrency involves locking rows at the data source to prevent users from modifying data in a way that affects other users. In a pessimistic model, when a user performs an action that causes a lock to be applied, other users cannot perform actions that would conflict with the lock until the lock owner releases it. This model is primarily used in environments where there is heavy contention for data, where the cost of protecting data with locks is less than the cost of rolling back transactions if concurrency conflicts occur.

Therefore, in a pessimistic currency model, a user who reads a row with the intention of changing it establishes a lock. Until the user has finished the update and released the lock, no one else can change that row. For this reason, pessimistic concurrency is best implemented when lock times will be short, as in programmatic processing of records. Pessimistic concurrency is not a scalable option when users are interacting with data, causing records to be locked for relatively large periods of time.

By contrast, users who use optimistic concurrency do not lock a row when reading it. When a user wants to update a row, the application must determine whether another user has changed the row since it was read. Optimistic concurrency is generally used in environments with a low contention for data. This improves performance as no locking of records is required, and locking of records requires additional server resources. Also, in order to maintain record locks, a persistent connection to the database server is required. Because this is not the case in an optimistic concurrency model, connections to the server are free to serve a larger number of clients in less time.

In an optimistic concurrency model, a violation is considered to have occurred if, after a user receives a value from the database, another user modifies the value before the first user has attempted to modify it.

 

LINQPad

If you've not used nor know what LINQPad is...... tut tut tut

Download it form here

http://www.linqpad.net/  it will make your life easier, infact you'll wonder whatever you did without it...

So how does it help...? try it and see :-)