簡體   English   中英

使用DataTemplate在WPF中通過LINQ to SQL進行雙向綁定,以獲取ListBox的ListItem的屬性

[英]Two way binding in WPF trough LINQ to SQL for the property of a ListItem of a ListBox using a DataTemplate

我是C#和WPF的新手。 盡管我閱讀了大量的文檔,教程和以前的問題,但我似乎無法找到我的場景。

我有的

我在C#中有一個WPF應用程序,其中包含一個包含ListBox的Window。 ListBox定義了一個DataTemplate,用於為每個ListItem顯示帶有TextBox的項目。

我在同一台機器上有一個Microsoft SQL Express服務器,它包含一個名為Test的數據庫,其中包含一個名為Client的視圖,它公開了另一個表的列id INT PRIMARY KEY IDENTITYname VARCHAR(50) NOT NULL ,以及一個名為Client_update(@id, @name)的存儲過程Client_update(@id, @name) id ,@ name Client_update(@id, @name)通過同一個表上的簡單UPDATE語句設置id@id的客戶端的name列。

我想要實現的目標

我想要實現的是在窗口加載時填充ListBox,並通過將焦點切換到另一個組件來對數據(包含在文本框中)的更改持久保存到數據庫(通過存儲過程)的GUI。

我做了什么

我使用Visual Studio向項目中添加了一個新的LINQ to SQL Classes元素,從而創建了一個名為DataClassesDataContext的DataContext類。 我使用Visual Studio中的OR Designer將視圖映射到Class Client ,將存儲過程映射到Client_update(id, name) 然后我設置(再次使用OR Designer的GUI)表Client的主鍵為id ,其默認編輯方法為Client_update(id, name) (負責匹配存儲過程和方法的參數)。

我的XAML代碼(文件MainWindow.xaml.cs )是:

<Window x:Class="Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Loaded="Window_Loaded">
    <ListBox x:Name="myListBox">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBox Text="{Binding Path=name Mode=TwoWay}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Window>

我已將TextBox Text屬性設置為綁定到要在運行時在稍后顯示的代碼隱藏中設置的源的name屬性,在TwoWay模式下。 TextBox上的數據更新的默認觸發器應該是OnLostFocus,所以我沒有指定它。

我的代碼隱藏(文件MainWindow.cs )是:

namespace Test
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //Initialize the data context
            DataClassesDataContext dataContext = new DataClassesDataContext();

            //Define the query to retrieve the list of clients from the SQL Server
            IEnumerable<Client> clients = from c in dataContext.Client
                                          select c;

            /* Set the item source to be the result of the query defined earlier
             * (This also gets the query executed)
             */
            myListBox.ItemsSource = clients;
        }
    }
}

我得到了什么

首先,應用程序將無法運行。 System.Data.Linq.dll中類型System.InvalidOperationException的未處理異常,其中包含“成員'id'的錯誤AutoSync規范”。 被扔了。

在線搜索我發現,默認情況下,OR Designer會將AutoSync規范設置為主鍵列上的Always OnUpdate上設置它會引發同樣的問題,同時將其設置為OnInsertNever ,可以解決問題。

但是,在這兩個值上設置它會使我的應用程序僅部分運行,數據會顯示,但更改不會持久保存到數據庫中。 (我在編輯應用程序上的數據后用Microsoft SQL Management Studio手動檢查)

我有什么問題

什么是AutoSync參數以及為什么會引發異常? 這是在這種情況下定義雙向綁定的正確方法,還是我完全走錯了方向? 如果是這樣,你能否給我任何提示,指出我正確的策略?

PS我很抱歉,如果代碼沒有正確突出顯示,我已閱讀並嘗試使用語法來應用Prettify,但由於某種原因,XAML沒有選項,甚至使用XML和C#(cs)作為語言標簽不起作用,我不明白為什么。

編輯#1:突出顯示正在工作,它只是未在預覽中顯示。

編輯#2:修正了一些拼寫錯誤,視圖的名稱,存儲過程和類是單一的。 (即Client不是Clients

嘗試將dataContext定義為全局變量。 那么只要改變從對象dataContext需要提交,調用dataContext.SubmitChanges(); 應該按需要通過調用SubmitChanges()方法同步到數據庫(實時太昂貴):

DataClassesDataContext dataContext = new DataClassesDataContext();
......
private void ButtonSubmit_Click(object sender, RoutedEventArgs e)
{
    dataContext.SubmitChanges();
}

更新:( 作為評論的respoind)

這是我所知道的使用LINQ to SQL持久更改數據庫的方式。 DataContext通過跟蹤對從db檢索的實體的更改來工作,當SubmitChanges調用發送回db的所有更改時。

TwoWay模式綁定不涉及application-to-db和db-to-application。 它是[綁定UI控件屬性] -to- [綁定源],反之亦然。 當用戶在TextBox中更改名稱時,Client實體中的name屬性將反映該更改,如果實體中的名稱從代碼更改,TextBox將顯示更新的名稱。 在這種情況下,這就是雙向的意思。 但所有這些更改都在應用程序中,在調用SubmitChanges之前不會提交給db。

我不完全了解AutoSync屬性,你可以參考這個SO答案 ,看看是否有助於你理解它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM