如何在自定义 WPF 用户控件中正确使用 CoerceValueCallback

发布于 2024-11-26 14:50:22 字数 1473 浏览 1 评论 0原文

我创建了一个用户控件,我团队的其他成员只需将其放置在他们的视图上,然后他们可以动态创建按钮的 ObservrableCollection 并绑定到它(功能区栏,但根据我们的需求高度定制),它处理放置、样式它工作得很好,完全符合我们项目的需要,但它只在初始加载时工作,我做了一些挖掘并意识到这是因为我在 FrameWorkMetaData 中只有一个 PropertyChangedCallback 并且我没有设置回调这CoerceValueCallback 所以我做了一些挖掘并设置了一个,但我不确定到底要做什么 - 我想这就是问题,CoerceValueCallback 的方法签名让它返回一个对象,我只想在列表出现时更新我的​​按钮变化。忽略这个返回值是否安全?也许一些代码可能会有所帮助-

这是我的PropertyChangedCallback-当他们第一次分配按钮列表时被解雇

 public static void ButtonListUpdated(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
  int count = 0;
  var grid = (source as RibbonBarUserControl).ButtonsGrid;
  var buttons = e.NewValue as ObservableCollection<Button>;
  if (buttons != null)
  {
    grid.Children.Clear();
    foreach (RibbonButton b in buttons)
    {
      b.Margin = new Thickness(1);
      b.Style = (Style)grid.FindResource("ribbonButtonStyle");
      ColumnDefinition c = new ColumnDefinition();
      grid.ColumnDefinitions.Add(c);
      grid.Children.Add(b);
      Grid.SetRow(b, 0);
      Grid.SetColumn(b, count);
      count = ++count;
    }
  }
}

这里没有CoerceValueCallback

 public static object OnButtonListModified(DependencyObject sender, Object baseValue)
{
  //What to do here? Can I essentially ignore the returned object and basically 
  //copy what I am doing in ButtonListUpdated?
  return baseValue;
}

我在网上看到了一些例子,它们更简单-就像生日小于结婚年生日=结婚年,当然这有点不同 - 我正在创建按钮并更新控件的 UI。

好的 - 感谢您的任何建议!

I have created a user control, the other members of my team simply place it on their view and they can then dynamically create an ObservrableCollection of buttons and bind to it (a ribbon bar but highly customized to our needs), it handles placement, style etc. It works just fine and totally fits the need for our project however it only works upon initial load, I did some digging and realized that it was because I only had a PropertyChangedCallback in the FrameWorkMetaData and I didn't set up a callback for the CoerceValueCallback so I did some digging and set one up but I am not sure exactly what to do - I guess here is the question, the method signature of the CoerceValueCallback has it returning an object and I just want to update my buttons when ever the list changes. Is it safe to ignore this return value? Maybe some code might help -

Here is my PropertyChangedCallback - gets fired when they first assign the list of buttons

 public static void ButtonListUpdated(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
  int count = 0;
  var grid = (source as RibbonBarUserControl).ButtonsGrid;
  var buttons = e.NewValue as ObservableCollection<Button>;
  if (buttons != null)
  {
    grid.Children.Clear();
    foreach (RibbonButton b in buttons)
    {
      b.Margin = new Thickness(1);
      b.Style = (Style)grid.FindResource("ribbonButtonStyle");
      ColumnDefinition c = new ColumnDefinition();
      grid.ColumnDefinitions.Add(c);
      grid.Children.Add(b);
      Grid.SetRow(b, 0);
      Grid.SetColumn(b, count);
      count = ++count;
    }
  }
}

No here is the CoerceValueCallback

 public static object OnButtonListModified(DependencyObject sender, Object baseValue)
{
  //What to do here? Can I essentially ignore the returned object and basically 
  //copy what I am doing in ButtonListUpdated?
  return baseValue;
}

I saw some examples online and they where much simpler - like if birthday is less than marriage year birthday = marriage year, course this is a little different - I am creating buttons and updating the UI of my control.

OK - Thanks for any suggestions!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧城烟雨 2024-12-03 14:50:22

我认为您不需要使用 CoerceValueCallback。相反,您应该挂钩 CollectionChanged 您的收藏事件并在触发时更新您的按钮。

例如:

public static void ButtonListUpdated(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
    var control = source as RibbonBarUserControl;
    var buttons = e.OldValue as ObservableCollection<Button>;
    if (buttons != null)
        buttons.CollectionChanged -= control.OnCollectionChanged;

    buttons = e.NewValue as ObservableCollection<Button>;
    if (buttons != null)
        buttons.CollectionChanged += control.OnCollectionChanged;

    control.UpdateButtons();
}

private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    this.UpdateButtons();
}

private void UpdateButtons() {
    // TODO: Update buttons
}

您还可以使用 NotifyCollectionChangedEventArgs 的成员来确定集合如何更改,并对按钮进行最小的更改。或者你可以每次都完全重建它们。

I don't think you need to use a CoerceValueCallback. Instead, you should hook into the CollectionChanged event of your collection and update your buttons when that is fired.

So something like:

public static void ButtonListUpdated(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
    var control = source as RibbonBarUserControl;
    var buttons = e.OldValue as ObservableCollection<Button>;
    if (buttons != null)
        buttons.CollectionChanged -= control.OnCollectionChanged;

    buttons = e.NewValue as ObservableCollection<Button>;
    if (buttons != null)
        buttons.CollectionChanged += control.OnCollectionChanged;

    control.UpdateButtons();
}

private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    this.UpdateButtons();
}

private void UpdateButtons() {
    // TODO: Update buttons
}

You could also use the members of NotifyCollectionChangedEventArgs to determine how the collection changed, and make minimal changes to buttons. Or you could just completely rebuild them everytime.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文