2014-06-26 124 views
2

我是新來WPF和這個奇特結合的東西,接着這些tutorial和得到這個XAML如何將命令綁定到按鈕

<Button 
    x:Name="btn" 
    Content="refresh" 
    Command="{Binding RefreshCmd}" /> 

和驗證碼:

public someClass() 
{ 
    InitializeComponent(); 

    CreateRefreshCmd(); 
    btn.DataContext=this; // without this line it will not work !! 
} 

public ICommand RefreshCmd 
{ 
    get; 
    internal set; 
} 

private bool CanExecuteRefreshCmd() 
{ 
    return true; 
} 

private void CreateRefreshCmd() 
{ 
    RefreshCmd=new RelayCommand(e => RefreshExec(), c => this.CanExecuteRefreshCmd()); 
} 

public void RefreshExec() 
{ 
    // do something fancy here ! 
} 

但沒有構造函數中的最後一行它將不起作用。

在教程中這行不存在。

我該如何避免這種情況?

編輯:

我點擊了與Visual Studio中的數據綁定和得到這個:

Command="{Binding RefreshCmd, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type my:spielerei}}}" 

這真的有必要嗎?

+0

在DataContext可能會在您的教程視圖的XAML來設置。 http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.datacontext.aspx –

回答

4

對於綁定工作,您需要爲綁定設置數據上下文目標,所以是的,這是必要的。在您的編輯中發佈的Command綁定中,綁定被指示尋找Button類型my:spielerei控件的祖先上的RefreshCmd屬性,我認爲它是包含窗口類型。這就是爲什麼DataContext的顯式設置沒有出現在教程中。

綁定和命令可用於代碼隱藏,但更常用於MVVM模式中的視圖模型。這涉及到將類的DataContext設置爲包含要綁定到的屬性和命令的視圖模型。要改變你的代碼遵循MVVM,我們需要一個視圖模型:

public class SomeClassViewModel 
{ 
    public SomeClassViewModel() 
    { 
     this.RefreshCmd = new RelayCommand(e => RefreshExec(), c => this.CanExecuteRefreshCmd()); 
    } 

    public ICommand RefreshCmd { get; internal set; } 

    private bool CanExecuteRefreshCmd() 
    { 
     return true; 
    } 

    public void RefreshExec() 
    { 
     // do something fancy here ! 
    } 
} 

然後,在後臺代碼,創建視圖模型,並將其指定爲對象的數據上下文:

public class SomeClass 
{ 
    public SomeClass() 
    { 
     InitializeComponent(); 

     this.DataContext = new SomeClassViewModel(); 
    } 
} 

請注意,SomeClass代碼隱藏文件中的所有代碼已移至視圖模型 - 它現在可以測試,並且您的XAML控件可以通過綁定到屬性並執行命令與視圖模型進行通信。需要

+0

謝謝,非常好的解釋。代碼勝過千言萬語!我必須在接下來的幾天裏初始化這些MVVM的東西! – mxii

0

如果存在可綁定的對象,則綁定將正常工作。此對象是從DataContext屬性中讀取的。如果未設置此屬性,則沒有任何可綁定的內容。這就是爲什麼需要以下行:

btn.DataContext=this; 

你提到的教程做它,即它設置的DataContext在XAML一點點不同的方式。請檢查本教程中的MainWindow.xaml文件。它包含在其中填充的DataContext財產開始下面的代碼:

<Window x:Class="MvvmCommand.MainWindow" DataContext="{Binding Main, Source={StaticResource Locator}}"> 
+0

我沒有下載教程代碼..對不起。謝謝你的時間! – mxii

0

當您使用WPF綁定,默認情況下它設置綁定到具有屬性的對象的DataContext的命名屬性這是有約束力的。所以在你的例子中,按鈕的DataContext。 這個屬性是通過樹繼承下來的,所以如果沒有在按鈕上設置,它會一直查找樹到保存控件的窗口。

MSDN on binding

沒有所有的XAML翻閱我也有猜測,但我猜你沒有設置託管按鈕窗口的datacontext。通過明確地將它設置在構造函數中,您將綁定的源設置爲具有該屬性的對象,因此它的工作原理爲何。

執行此操作的正常方法是將數據上下文設置爲包含該命令的類。通常的設計模式是MVVM。綁定的思想是分離 - 它不像你在後面的代碼中處理它們的事件,而是它允許你創建一個視圖模型或類似的類來暴露這些命令並將它綁定到視圖。這允許您通過視圖模型執行單元測試功能,而無需單元測試視圖,將視圖模型分享到多個視圖等。

0

數據上下文來進行設置,以便約束力的框架能夠解決的值

你可能設置你使用

相同

第一種方法的另一種方法是將各種方法通過xaml設置

<Window x:Class="Project.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    DataContext="{Binding RelativeSource={RelativeSource Self}}"> 

這裏的想法是將數據上下文設置爲self。

+0

沒有爲我工作? – mxii

0

總之,沒有必要。不要將datacontext設置爲按鈕,請在XAML中爲頁面(視圖)設置數據上下文(viemodel)。當然,您的命令必須通過該視圖模型公開。

對於另一個問題,我提出了簡單的展示命令結合和交叉視圖模型的溝通,看看這裏https://github.com/mikkoviitala/cross-viewmodel-communication

相關問題