如何在每次打开 ContextMenu 时强制进行绑定评估?

发布于 2024-07-28 08:25:27 字数 688 浏览 2 评论 0原文

我有一个带有 MenuItem 的 ContextMenu:

<Grid>
    <Button Content="{Binding Test}">
        <Button.ContextMenu>
            <ContextMenu>
                <StackPanel>
                    <MenuItem Header="{Binding Test}"/>
                </StackPanel>
            </ContextMenu>
        </Button.ContextMenu>
    </Button>
</Grid>

Test 属性如下所示:

private Random rand;

public string Test
{
    get
    {
        return "Test " + this.rand.Next(50);
    }
}

当我右键单击该按钮时,我会看到“Test 41”。 下次我打开菜单时,我会得到相同的值。 有没有办法强制菜单每次都评估绑定? (然后有“测试 3”、“测试 45”、“测试 65”...

I have a ContextMenu with a MenuItem in it:

<Grid>
    <Button Content="{Binding Test}">
        <Button.ContextMenu>
            <ContextMenu>
                <StackPanel>
                    <MenuItem Header="{Binding Test}"/>
                </StackPanel>
            </ContextMenu>
        </Button.ContextMenu>
    </Button>
</Grid>

The Test property looks like the following:

private Random rand;

public string Test
{
    get
    {
        return "Test " + this.rand.Next(50);
    }
}

When I right click the button, I have, for instance "Test 41". Next times I open the menu I have the same value. Is there a way to force the Menu to evaluate the binding each time ? (and then having "Test 3", "Test 45", "Test 65"...

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

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

发布评论

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

评论(2

︶葆Ⅱㄣ 2024-08-04 08:27:12

您的 Test 属性需要在其值发生变化时通知其他组件,例如,通过在包含类中实现 INotifyPropertyChanged 接口,如下所示:

class Window1 : Window, INotifyPropertyChanged {

  ...

  private string m_Test;

  public string Test {
    get {
      return m_Test;
    }
    set {
      m_Test = value;
      OnPropertyChanged("Test");
    }
  }

}

然后您可以修改 的值通过使用属性 (Test = "newValue";) 从任何地方进行测试,更改将反映在 UI 上。

如果您确实需要在显示 ContextMenu 时更改属性的值,请使用 ContextMenuOpend 事件:

Xaml:

<ContextMenu Opened="UpdateTest">
  <MenuItem Header="{Binding Test}" />
</ContextMenu>

Code-在后面:

private void UpdateTest(object sender, RoutedEventArgs e) {
  // just assign a new value to the property,
  // UI will be notified automatically
  Test = "Test " + this.rand.Next(50);
}

Your Test property needs to inform other components whenever its value changes, e.g. by implementing the INotifyPropertyChanged interface in the containing class like this:

class Window1 : Window, INotifyPropertyChanged {

  ...

  private string m_Test;

  public string Test {
    get {
      return m_Test;
    }
    set {
      m_Test = value;
      OnPropertyChanged("Test");
    }
  }

}

You can then modify the value of Test from anywhere by using the property (Test = "newValue";) and the changes will be reflected on the UI.

If you really need to change the value of the property when the ContextMenu is shown, use the Opend event of the ContextMenu:

Xaml:

<ContextMenu Opened="UpdateTest">
  <MenuItem Header="{Binding Test}" />
</ContextMenu>

Code-behind:

private void UpdateTest(object sender, RoutedEventArgs e) {
  // just assign a new value to the property,
  // UI will be notified automatically
  Test = "Test " + this.rand.Next(50);
}
孤蝉 2024-08-04 08:26:42

这是我在相同情况下使用的一个技巧:

命名您的上下文菜单并创建您自己的 RoutedCommand,我将它们用于所有按钮和菜单,因为它们具有启用或禁用控件的 CanExecute 方法和调用执行操作的 Execute 方法工作。 每次打开上下文菜单时,都会调用 CanExecute 方法。 这意味着您可以进行自定义处理以查看是否应该启用它,或者您可以更改菜单的内容,这有利于在保存不同内容时更改菜单。 当用户编辑 xyx 时,我们用它来表示“保存 xyx..”。

无论如何,如果菜单已命名,您可以在 CanExecute 上修改其内容。 (如果命令源自菜单,无论如何,您都会将其作为事件 CanExecute 的发送者,但有时我喜欢将它们的范围扩大到更高,因为您可以为它们分配键盘快捷键,这些快捷键可以从它们范围内的任何地方执行。)

Here is a hack i use in the same situation:

Name your context menu and create your own RoutedCommand, i use these for all buttons and menus as they have a CanExecute method which enables or disables the control and an Execute method that gets called to do the work. every time a context menu opens the CanExecute method gets called. that means you can do custom processing to see if it should be enabled, or you can change the contents of the menu, good for changing menu's when saving different things. we use it to say, Save xyx.. when the user is editing an xyx.

anyway if the menu is named you can modify its content on the CanExecute. (if the command originates on the menu you will have it as the sender of the event CanExecute anyway, but sometimes i like to scope them higher as you can assign keyboard shortcuts to them which can be executed from anywhere they are scoped.)

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