2011-03-13 88 views
1

我一直在努力將TextBox.Text綁定到某個對象的公共屬性,但不幸的是我還沒有完成。如何將公共屬性綁定到WPF TextBox.Text屬性

實際XAML看起來像:

<Window 
    <!-- skipped --> 
    xmlns:local="clr-namespace:Dotnet.Samples.Foobar" 
    xmlns:system="clr-namespace:System;assembly=mscorlib"> 

    <Window.Resources> 
     <local:Foobar x:Key="foobar" Foo="Lorem" Bar="Ipsum" 
    </Window.Resources> 
    <!-- skipped --> 

     <TextBox Text="{Binding Source={StaticResource foobar}, Path=Foo}"> 
     <TextBox Text="{Binding Source={StaticResource foobar}, Path=Bar}"> 
     <!-- skipped --> 
</Window> 

與數據提供程序對象是簡單:

public class Foobar 
{ 
    public string Foo { get; set; } 
    public string Bar { get; set; } 

    public Foobar() 
    { 

    } 
} 

我想我是那種與WPF的各種綁定選項的困惑和我米可能混合起來,所以任何建議將肯定讚賞。

編輯 - 所有的綁定工作正常,剩下的挑戰是通知從模型到ViewModel(另一種方式工作)的變化。我已經犯下的「破」的代碼來替代回購: http://nanotaboada.svn.beanstalkapp.com/dotnet/trunk/Dotnet.Samples.Rijndael/

隨意籤,我會很高興聽到這個任何反饋。非常感謝

回答

1

儘管您的構造函數方法參數是可選的,XAML綁定引擎仍未找到要使用的合適構造函數。因此,您必須傳入構造函數的值,或創建一個將Foo的值設置爲默認值的無參數構造函數,或根本不使用ObjectDataProvider,並直接創建類型的實例作爲資源。

... 
xmlns:system="clr-namespace:System;assembly=mscorlib" 
... 

<!-- Either create an instance of your type, and you can initialise the property values, this will require a default parameterless constructor --> 
<abc:Foobar x:Key="foobar2" Foo="Foo" /> 

<!-- or pass the optional parameter values into your existing constructor --> 
<ObjectDataProvider x:Key="foobar" ObjectType="{x:Type abc:Foobar}"> 
    <ObjectDataProvider.ConstructorParameters> 
    <system:String>Foo</system:String> 
    <system:String>Bar</system:String> 
    </ObjectDataProvider.ConstructorParameters> 
</ObjectDataProvider> 

注意,您只需要實現INotifyPropertyChanged如果你的綁定將在代碼中無效,你需要通知UI。如果你不喜歡在你的模型類型上實現這個接口,那麼你可以在你的視圖模型(假設你使用MVVM)上做到這一點,但是當你的模型需要找到另一種機制來通知你的視圖模型值改變。

+0

@devdigital:非常感謝您的詳細解釋!通過'Window.Resources'實現的類型實例化/構造在(我正在更新原始代碼)上工作正常,但仍然沒有得到它們的屬性集。讓我猜 - 我應該實現'INotifyPropertyChanged'嗎? – 2011-03-13 21:10:09

+1

不,您不需要在這種情況下 - 只需要通知UI已更改代碼,而不是相反方式,只需要通知屬性更改。你確定安裝者沒有被解僱嗎?默認情況下,TextBox只會更新失去焦點的屬性。如果要在更改屬性的同時更改此屬性,請在TextBox中鍵入屬性值,然後將綁定表達式中的UpdateSourceTrigger屬性值設置爲PropertyChanged。請參閱http://msdn.microsoft.com/en-us/library/system.windows.data.binding.updatesourcetrigger.aspx – devdigital 2011-03-13 21:36:50

+0

@devdigital:再次感謝您的回覆 - 我已嘗試'UpdateSourceTrigger = PropertyChanged'和'Mode = TwoWay'沒有更好的運氣。 – 2011-03-13 23:34:55

1

這看起來很好,除了我不認爲ObjectDataProvider能夠讀取默認參數。嘗試創建一個沒有任何參數的Foobar構造函數。

如果失敗了,您能否給我們提供您所看到的錯誤?

+0

@Rob:感謝您的評論 - 目前它編譯好,沒有錯誤,但TextBox.Text沒有顯示任何值,所以我會繼續嘗試,沒有默認參數。 – 2011-03-13 16:10:55

+0

@Rob:我剛剛嘗試刪除默認值並構建對象,但沒有奏效。 – 2011-03-13 16:15:28

+0

在輸出窗口中是否有任何綁定錯誤? – 2011-03-13 16:23:01

1

「不完全在那裏」是什麼意思?除了你在Foobar課中缺少變更通知外,一切看起來都很好。改變它,使其正確實施INotifyPropertyChanged,一切都應該正常工作。

+0

@Kent,感謝您的評論,「不完全在那裏」我的意思是「它沒有按預期工作」,我會嘗試您的建議,儘管我不確定是否應該將System.ComponentModel接口添加到與UI無關的類 - 應該有另一種方式來做到這一點。 – 2011-03-13 18:09:08

+0

我想我會嘗試http://updatecontrols.codeplex.com/ – 2011-03-13 19:26:45

+0

@Nano:'System.ComponentModel'與UI無關。 – 2011-03-13 23:10:29

1

我認爲這是在構造函數中的參數問題。如果你真的需要他們,你可以把它寫這樣的:

這也將需要這個補充說:xmlns:sys="clr-namespace:System;assembly=mscorlib"

然後是Foobar的類將是這樣的:

public class Foobar 
{ 
    public string Foo { get; set; } 
    public string Bar { get; set; } 

    public Foobar Foobar1(string param1 = "foo", string param2 = "bar") 
    { 
     Foobar f = new Foobar(); 
     f.Foo = param1; 
     f.Bar = param2; 
     return f; 
    } 
} 

擺脫/根據需要在XAML中添加參數。