2011年11月22日

[SQL]A connection was successfully established with the server, but then an error occurred during the login process

While try to connect to SQL server, I keep getting this error.

Solution is simple but wired, details please refer to William Vaughn’s blog

There are two solutions, I took the simplest one – when exception thrown, try to open connection again.

using (conn = CreateConnection()) {
try {
conn.Open();
}
catch {
/* http://betav.com/blog/billva/2008/11/solution-forcibly-closed-sql-s.html#more */
conn.Dispose();
conn = CreateConnection();
conn.Open();
}
//...
}

2011年11月11日

[WP7學習筆記] DataBinding (2)

繼續(1)的例子, 首先把ListBox的ItemTemplate跟Style一起做成Resource

<Style x:Key="Style_RadioButtonListItem" TargetType="ListBoxItem">
            <Setter Property="Padding" Value="3" />
            <Setter Property="VerticalContentAlignment" Value="Top" />
            <Setter Property="Background" Value="Red" />
            <Setter Property="Foreground" Value="Blue" />
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Grid Background="Yellow">
                            <RadioButton IsChecked="{Binding Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected}"/>
                            <TextBlock Foreground="{Binding Foreground, RelativeSource={RelativeSource TemplatedParent}}" TextWrapping="Wrap" Text="{Binding DataContext.CategoryDesc, RelativeSource={RelativeSource TemplatedParent}}"></TextBlock>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

其中這一段


<TextBlock Foreground="{Binding Foreground, RelativeSource={RelativeSource TemplatedParent}}" TextWrapping="Wrap" Text="{Binding DataContext.CategoryDesc, RelativeSource={RelativeSource TemplatedParent}}"></TextBlock>


因為這個TextBox是ListBoxItem Template的一部分, 他的資料來源是他的TemplatedParent, 也就是ListBox, 因此指定RelativeSource={RelativeSource TemplatedParent}.


另外因為我希望每個ListBoxItem都顯示出選項的說明, 因此指定Text屬性Bind到DateContext (在我的例子裡, 是一個Category物件)的CategoryDesc屬性.
ListBox則改寫為

<ListBox x:Name="_Categories" Grid.Row="1" Background="Blue"
                 SelectedItem="{Binding SelectedCollectionItem,Mode=TwoWay}"
                 ItemContainerStyle="{StaticResource Style_RadioButtonListItem}">

以程式指定ListBox的Items資料來源以及預設的選項

var categories = Data.DAL.Instance.QueryCategories();
_Categories.ItemsSource = categories;
_Categories.SelectedItem = _Categories.Items.First();//接下來應該有辦法可以讓這一段也用DataBinding的方式做才對…
 



結果如下…只能說,有沒有美感真的是差很多啊…XD


sp3

2011年11月10日

[WP7學習筆記] DataBinding (1)

假如我有一個資料結構是這樣    


public class TransactionRecord
{
public string CategoryID
{
get;set;
}
public string CategoryDesc
{
get;set;
}


public int Amount
{
get;set;
}
}

程式會透過資料存取取得所有的Category並顯示在ListBox中.


先定義主畫面


<phone:PhoneApplicationPage>
<!—省略—>


    <Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ScrollViewer>
<ItemsControl x:Name="_List">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border x:Name="_Border" x:FieldModifier="Private">
<!—省略—>
<Grid Tag="{Binding}" Height="120">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Foreground="Black" Grid.Column="0" Text="{Binding CategoryDesc}"/>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Foreground="Black" Text="{Binding CategoryID}"/>
<TextBlock Grid.Row="1" Foreground="Black" Text="{Binding Amount}"/>
</Grid>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</Grid>
</phone:PhoneApplicationPage>



其中的紅色粗體字型的地方即為我想要顯示的相對應的資料, 對應到資料結構的屬性. 然後在程式中指定



var records = Data.DAL.Instance.QueryRecords();
_List.ItemsSource = records;


結果


sp



如果我希望可以再畫面上修改金額, 並且直接把修改後的結果更心回資料集. 最簡單的做法是, 將顯示用的TextBlack改為TextBox, 並指定Binding Mode為Twoway如下



<TextBox Grid.Row="1" Height="84" Foreground="Black" InputScope="Number" Text="{Binding Amount, Mode=TwoWay}"/>


這時, 畫面上可以直接修改資料, 修改完後和下按鈕, 可以發現資料已經被修改了


private void button1_Click(object sender, RoutedEventArgs e)
{
var item = _List.Items[0] as Data.TransactionRecord;
MessageBox.Show(item.Amount.ToString());
}


sp2


這樣的方式, 資料是在離開TextBox時修改, 也就是Lost Focus時. 如果我希望的是在修改資料的當下就修改資料來源呢 ?


<TextBox Grid.Row="1" Height="84" Foreground="Black" InputScope="Number" Text="{Binding Amount, Mode=TwoWay,UpdateSourceTrigger=Explicit}" TextChanged="TextBox_TextChanged"/>



加入UpdateSourceTrigger=Explicit, 並指定TextChanged的Event Handler



        private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
BindingExpression exp = (sender as TextBox).GetBindingExpression(TextBox.TextProperty);
exp.UpdateSource();
PageTitle.Text = "Amount=" + (_List.Items[0] as TransactionRecord).Amount.ToString();
}


修改的結果會立刻反應到資料來源

2011年11月1日

[WP7]取得組件中的XML檔案內容

首先,把檔案的build action設為Resource

image

使用Application.GetResourceStream()取得內容

var ri = Application.GetResourceStream(new Uri("MyDatabase.Demo;component/InitData/InitData.xml", UriKind.Relative));
if(ri != null){
   using(var sr = new System.IO.StreamReader(ri.Stream)){
      var xml = sr.ReadToEnd();
   }
}

[NoSQL]Sterling Database

最近在survey之後案子也許會用到的NoSQL Solution, 這是目前在CodePlex上滿受歡迎的一個解決方案. Sterling NoSQL OODB for .Net

首先, 撰寫自己的Sterling Service如下

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Wintellect.Sterling.Database;
using Wintellect.Sterling;
namespace MoneyBook.Data.DBHelpers
{
    public class MBookDBService : IApplicationService, IApplicationLifetimeAware, IDisposable
    {
        private SterlingEngine _engine = null;
        private SterlingDefaultLogger _logger = null;
        public ISterlingDatabaseInstance Database { get; private set; }
        #region IApplicationService Members
        public void StartService(ApplicationServiceContext context)
        {
            if (System.ComponentModel.DesignerProperties.IsInDesignTool)
                return;
            if (_engine != null)
            {
                StopService();
                Dispose();
            }
            _engine = new SterlingEngine();
            
        }
        public void StopService()
        {
            
        }
        #endregion
        #region IApplicationLifetimeAware Members
        public void Exited()
        {
            Dispose();
        }
        public void Exiting()
        {
            if (System.ComponentModel.DesignerProperties.IsInDesignTool)
            {
                return;
            }
            if (System.Diagnostics.Debugger.IsAttached && _logger != null)
            {
                _logger.Detach();
            }
        }
        public void Started()
        {
        }
//remove first lunch flag
        private static void DeleteFirstLunchFlag()
        {
            using (System.IO.IsolatedStorage.IsolatedStorageFile file = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (file.FileExists("/MBook/lunched.txt"))
                {
                    file.DeleteFile("/MBook/lunched.txt");
                }
            }
        }
//Check if this is the first time we lunching this database instance
        private static bool IsFirstLunch()
        {
            using (System.IO.IsolatedStorage.IsolatedStorageFile file = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication())
            {
                return file.FileExists("/MBook/lunched.txt");
            }
        }
//Set first lunch flag
        private static void SetFirstLunchFlag()
        {
            using (System.IO.IsolatedStorage.IsolatedStorageFile file = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (!file.FileExists("/MBook/lunched.txt"))
                {
                    try
                    {
                        file.CreateFile("/MBook/lunched.txt").Write(new byte[] { 0x31 }, 0, 1);
                    }
                    catch { }
                }
            }
        }
        public void Starting()
        {
            if (System.ComponentModel.DesignerProperties.IsInDesignTool)
                return;
            _engine.Activate();
            Database = _engine.SterlingDatabase.RegisterDatabase<MBookDatabase>();
//Check if this is the first time, if so, setup initial data
//--NOTE-- this is only for testing purpose
            if (IsFirstLunch())
            {
                var db = (Database as MoneyBook.Data.DBHelpers.MBookDatabase);
                var cs = db.GetInitCategories();
                foreach (var c in cs)
                {
                    Database.Save(c);
                }
                SetFirstLunchFlag();
            }
        }
        #endregion
        #region IDisposable Members
        public void Dispose()
        {
            if (_engine != null)
            {
                _engine.Dispose();
                _engine = null;
            }
//Also, delete the flag, this is only for testing purpose
            DeleteFirstLunchFlag();
            GC.SuppressFinalize(this);
        }
        #endregion
    }
}


然後撰寫自己的Database



public partial class MyDatabase: BaseDatabaseInstance
    {
//override this method to create our own table definations
        protected override System.Collections.Generic.List<ITableDefinition> RegisterTables()
        {
            System.Collections.Generic.List<ITableDefinition> tables = new System.Collections.Generic.List<ITableDefinition>();
            //Add book table
            tables.Add(CreateTableDefinition<MBook, string>(x => x.BookID));
            //Add record table
            tables.Add(CreateTableDefinition<MRecord, string>(x => x.ID).WithIndex<MRecord, DateTime, string>("Index_MRecord_Date", x => x.Date));
            //Add category table
            tables.Add(CreateTableDefinition<MCategory, string>(x => x.CategoryID));
            //Add subcategory table
            tables.Add(CreateTableDefinition<MSubcategory, string>(x => x.SubcategoryID));
            return tables;
        }


使用前必須在App.xml中註冊為ApplicationLifetimeObject



<Application 
    x:Class="MoneyBook.UI.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"       
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:MBook="clr-namespace:MyDatabasae.Data.DBHelpers;assembly=MyDatabase.Data"
    xmlns:Sterling="clr-namespace:Wintellect.Sterling;assembly=Wintellect.Sterling.WindowsPhone">
    <!--Application Resources-->
    <Application.Resources>
    </Application.Resources>
    <Application.ApplicationLifetimeObjects>
        <!--Required object that handles lifetime events for the application-->
        <shell:PhoneApplicationService 
            Launching="Application_Launching" Closing="Application_Closing" 
            Activated="Application_Activated" Deactivated="Application_Deactivated"/>
        <MBook:MBookDBService/><!--Here-->
    </Application.ApplicationLifetimeObjects>
<!---->
</Application>


查詢資料



return MDBInstance.Query<MyDatabase.MCategory, string>().Select(x => x.LazyValue.Value).ToList();

Blog Archive

About Me