簡體   English   中英

綁定到依賴屬性,而依賴屬性又綁定到另一個綁定源

[英]Binding to Dependency Property which is, in turn, bound to another binding source

這很難解釋,但我會盡我所能。 我希望有一個可重復使用的控件,它有3個按鈕,一個用於創建實體,另一個用於編輯,另一個用於刪除,這里是相關部分的縮寫XAML。

-

<!-- ActionButtons.xaml -->

<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top">
        <Button Name="btnNew" Content="New" Command="{Binding Path=NewCommand}" />
        <Button Name="btnEdit" Content="Edit" Command="{Binding Path=EditCommand, Mode=OneWay}" />
        <Button Name="btnDelete" Content="Delete" Command="{Binding Path=DeleteCommand, Mode=OneWay}" />
    </StackPanel>

-

然后,在后面的代碼中我有dpprops聲明:

// ActionButtons.xaml.cs

public uscActionButtons()
{
            InitializeComponent();
            this.DataContext = this;
        }

        public ICommand NewCommand
        {
            get { return (ICommand)GetValue(NewCommandProperty); }
            set { SetValue(NewCommandProperty, value); }
        }

        // Using a DependencyProperty as the backing store for NewCommand.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty NewCommandProperty =
            DependencyProperty.Register("NewCommand", typeof(ICommand), typeof(uscActionButtons), new UIPropertyMetadata(null, new PropertyChangedCallback(OnCommandChanged)));

我想將NewCommand屬性綁定到另一個控件中的特定實現。 樣本用途:

<!-- SomeControl.xaml -->
<common:uscActionButtons Grid.Row="0" HorizontalAlignment="Left" 
                                 NewCommand="{Binding NewItemCommand}"
                                 />

// SomeControlViewModel.cs
// Note: SomeControlViewModel IS in the DataContext of SomeControl.
public ICommand NewItemCommand
        {
            get
            {
                if (mNewItemCommand == null)
                {
                    mNewItemCommand = new RelayCommand(x => this.CreateItem());
                }

                return mNewItemGroupCommand;
            }
        }

問題是可重用控件(ActionButtons)沒有看到NewItemCommand。 如果我使用一個簡單的按鈕,它看起來很好。 似乎問題是這種“鏈式”綁定。 但我知道這是可能的,WPF按鈕有一個Command依賴屬性,你可以綁定你的命令,所以創建我自己的可重用控件暴露ICommand依賴屬性一定不是那么難。

有任何想法嗎?

謝謝


編輯:這是解決方案,我所要做的就是將FindSource與FindAncestor一起使用。

<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top">
        <Button Name="btnNew" Content="New" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=my:uscActionButtons}, Path=NewCommand, Mode=OneWay}" />
        <Button Name="btnEdit" Content="Edit" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=my:uscActionButtons}, Path=EditCommand, Mode=OneWay}" />
        <Button Name="btnDelete" Content="Delete" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=my:uscActionButtons}, Path=DeleteCommand, Mode=OneWay}" />
    </StackPanel>

您看到的問題是您正在改變ActionButtons控件的DataContext 在構造函數中設置其DataContext時,您在其上指定的所有Bindings (甚至來自實例化它的外部XAML)都將指向新的DataContext 因此,當您在SomeControl中應用Binding時,Binding正在嘗試綁定DataContext ,這恰好是ActionButtons實例。

我不認為Control應該設置自己的DataContext ,因為它會導致你看到的錯誤。 如果你想使用UserControl (我可能會自己使用Control以便我可以做TemplateBindings ),那么你可以使用RelativeSource綁定(正如你在Snowbear的評論中提到的那樣),並且Bindings應該可以工作。

這是我的代碼中缺少的內容:

<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top">
        <Button Name="btnNew" Content="New" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=my:uscActionButtons}, Path=NewCommand, Mode=OneWay}" />
        <Button Name="btnEdit" Content="Edit" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=my:uscActionButtons}, Path=EditCommand, Mode=OneWay}" />
        <Button Name="btnDelete" Content="Delete" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=my:uscActionButtons}, Path=DeleteCommand, Mode=OneWay}" />
    </StackPanel>

我不得不將FindSource與FindAncestor一起使用。

謝謝你的所有答案!

this.DataContext = this;

這似乎是個問題,因為在這個XAML中:

 NewCommand="{Binding NewItemCommand}"

你綁定到ActionButtons本身的NewItemCommand。 這就是為什么在我看來設置內部控件的自我DataContext是壞模式的原因。 如果你確實需要這個DataContext(你),那么將它設置為頂層內部元素(在你的情況下為StackPanel)

Visual Studio調試器也可以幫助您調試綁定。 如果您將運行帶有調試器的應用程序,那么在Visual Studio的輸出窗口中您將看到綁定錯誤並且它們通常很容易理解,錯誤會讓您知道對於此特定綁定,它在ActionButtons實例中查找NewItemCommand屬性而不是你期待的課程。

更新在VS中測試您的代碼。 輸出窗口中出錯:

System.Windows.Data Error: 40 : BindingExpression path error: 'NewItemCommand' property not found on 'object' ''uscActionButtons' (Name='')'. BindingExpression:Path=NewItemCommand; DataItem='uscActionButtons' (Name=''); target element is 'uscActionButtons' (Name=''); target property is 'NewCommand' (type 'ICommand')
System.Windows.Data Error: 40 : BindingExpression path error: 'EditCommand' property not found on 'object' ''uscActionButtons' (Name='')'. BindingExpression:Path=EditCommand; DataItem='uscActionButtons' (Name=''); target element is 'Button' (Name='btnEdit'); target property is 'Command' (type 'ICommand')
System.Windows.Data Error: 40 : BindingExpression path error: 'DeleteCommand' property not found on 'object' ''uscActionButtons' (Name='')'. BindingExpression:Path=DeleteCommand; DataItem='uscActionButtons' (Name=''); target element is 'Button' (Name='btnDelete'); target property is 'Command' (type 'ICommand')

您是否可以錯過這些錯誤,例如因為打開輸出窗口太晚了?

更新2:

修復與替換你的:

this.DataContext = this;

和我的:

root.DataContext = this; //root - name for stackpanel

暫無
暫無

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

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