从另一个依赖属性更新一个依赖属性

7

我有一个字符串依赖属性(SearchText),当更新时,需要更新一个集合依赖属性(Results)。
我的集合依赖属性:

public IEnumerable<string> Results{
  get { return (IEnumerable<string>) GetValue(ResultsProperty); }
  set { SetValue(ResultsProperty, value); }
}
public static readonly DependencyProperty ResultsProperty= 
DependencyProperty.Register("Results", typeof(IEnumerable<string>), typeof(MainWindowVM), new UIPropertyMetadata(new List<string>()));

我尝试过这个方法,但没有成功。我在“Results = ...”行设置了断点,但它从未被触发。
public string SearchText{
  get { return (string) GetValue(SearchTextProperty); }
  set {
    Results =
          from T in Tree.GetPeople(value)
          select T.FullName;
    SetValue(SearchTextProperty, value);
  }
}
public static readonly DependencyProperty SearchTextProperty= 
DependencyProperty.Register("SearchText", typeof(string), typeof(MainWindowVM), new UIPropertyMetadata(""));

XAML:

<TextBox DockPanel.Dock="Top" Text="{Binding SearchValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

<ListBox DockPanel.Dock="Top" ItemsSource="{Binding NameResults}" SelectedItem="{Binding Search}" />

这段文本是关于IT技术方面的内容。它展示了XAML语言的使用,其中包括两个控件:一个文本框和一个列表框。通过绑定SearchValue属性,文本框可以实现双向数据绑定,同时也可以使用UpdateSourceTrigger属性来指定何时更新源数据。列表框则使用ItemsSource属性来指定绑定的数据源,而SelectedItem属性则用于指定选中项的值。
3个回答

15

在XAML或绑定中设置依赖属性时,运行时将始终绕过实例属性别名并直接调用GetValueSetValue。因此,您的实例setter没有被调用。

您可能希望考虑注册一个方法到依赖属性中,在属性更改时将其调用。这在创建依赖属性的PropertyMetadata时最容易完成。

我相信下面的示例可以达到您想要的效果。在示例中,我的类有两个别名为First和Second的依赖属性。当我设置First的值时,会调用我的更改处理程序,并设置Second的值。

public class DependencyPropertyTest : DependencyObject
{
  public static readonly DependencyProperty FirstProperty;
  public static readonly DependencyProperty SecondProperty;

  static DependencyPropertyTest()
  {
    FirstProperty  = DependencyProperty.Register("FirstProperty", 
                                                  typeof(bool), 
                                                  typeof(DependencyPropertyTest), 
                                                  new PropertyMetadata(false, FirstPropertyChanged));

    SecondProperty = DependencyProperty.Register("SecondProperty", 
                                                 typeof(string), 
                                                 typeof(DependencyPropertyTest), 
                                                 new PropertyMetadata(null));
  } // End constructor

  private bool First
  {
    get { return (bool)this.GetValue(FirstProperty); }
    set { this.SetValue(FirstProperty, value);       }

  } // End property First

  private string Second
  {
    get { return (string)this.GetValue(SecondProperty); }
    set { this.SetValue(SecondProperty, value);         }

  } // End property Second

  private static void FirstPropertyChanged(DependencyObject dependencyObject, 
                                           DependencyPropertyChangedEventArgs ea)
  {
    DependencyPropertyTest instance = dependencyObject as DependencyPropertyTest;

    if (instance == null)
    {
      return;
    }

    instance.Second = String.Format("First is {0}.", ((bool)ea.NewValue).ToString());

  } // End method FirstPropertyChanged
} // End class DependencyPropertyTest
我希望这能有所帮助。

-1,这将会打破对“Second”属性的绑定,因为将使用SetValue而不是SetCurrentValue(请参见https://dev59.com/C2855IYBdhLWcg3woV_M)。 - Benlitz
3
今天的情况是这样的,我同意。但是,在回答写作时,.NET Framework 3.5是最新版本,它没有SetCurrentValue成员。(参考:https://msdn.microsoft.com/en-us/library/system.windows.dependencyobject_members(v=vs.90).aspx)这值得评论或额外的答案来现代化,但在我看来,它不值得被投反对票。 - Jesse Squire

10

正如我所评论的,当前被接受的答案在原则上是正确的,除了它必须使用SetCurrentValue方法而不是进行简单赋值。请参见这个答案了解更多关于它的说明。

以下是已经修复过的相同代码:

public class DependencyPropertyTest : DependencyObject
{
  public static readonly DependencyProperty FirstProperty;
  public static readonly DependencyProperty SecondProperty;

  static DependencyPropertyTest()
  {
    FirstProperty  = DependencyProperty.Register("FirstProperty", 
                                                  typeof(bool), 
                                                  typeof(DependencyPropertyTest), 
                                                  new PropertyMetadata(false, FirstPropertyChanged));

    SecondProperty = DependencyProperty.Register("SecondProperty", 
                                                 typeof(string), 
                                                 typeof(DependencyPropertyTest), 
                                                 new PropertyMetadata(null));
  } // End constructor

  private bool First
  {
    get { return (bool)this.GetValue(FirstProperty); }
    set { this.SetValue(FirstProperty, value);       }

  } // End property First

  private string Second
  {
    get { return (string)this.GetValue(SecondProperty); }
    set { this.SetValue(SecondProperty, value);         }

  } // End property Second

  private static void FirstPropertyChanged(DependencyObject dependencyObject, 
                                           DependencyPropertyChangedEventArgs ea)
  {
    DependencyPropertyTest instance = dependencyObject as DependencyPropertyTest;

    if (instance == null)
    {
      return;
    }

    // SetCurrentValue should be used here!
    instance.SetCurrentValue(SecondProperty,
      String.Format("First is {0}.", ((bool)ea.NewValue).ToString());

  } // End method FirstPropertyChanged
} // End class DependencyPropertyTest

0
你在依赖属性上设置的顺序非常重要,放在类文件中的第一个将首先被执行,然后是其下面的。
class A {
dependecy 1
dependecy 2 
dependecy 3
}

它将按照类上设置的顺序进行调用,因此只需按照您想要的顺序对依赖项进行排序 如果1依赖于2->先放2,然后放1,就像这样

class A {
dependecy 2 
dependecy 1
dependecy 3
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接