繁体   English   中英

在menuitem的标题中绑定ElementName

[英]Binding ElementName in menuitem's header

我尝试将MenuItem标头中的TextBox文本绑定到MenuItem的Tag属性。 但它无法正常工作,请在Tag属性中始终获取Null。

代码如下

        <Button x:Name="Button1" Content="Test" HorizontalAlignment="Left" Width="182" Height="34" VerticalAlignment="Top" Margin="160,113,0,0">
        <Button.ContextMenu>
            <ContextMenu PlacementTarget="{Binding ElementName=Button1}" Placement="Bottom">
                <MenuItem Tag="{Binding ElementName=TextBox1, Path=Text}" Click="MessageBox_ShowTag">
                    <MenuItem.Header>
                        <Grid Height="25" MinWidth="153">
                            <Label Content="Label1" Width="86" HorizontalAlignment="Left" VerticalContentAlignment="Center"/>
                            <TextBox x:Name="TextBox1" VerticalContentAlignment="Center" Margin="91,0,0,0"/>
                        </Grid>
                    </MenuItem.Header>
                </MenuItem>
            </ContextMenu>
        </Button.ContextMenu>
    </Button>

单击菜单项时,调用MessageBox以在MenuItem中显示标签(MessageBox.Show((sender as MenuItem).Tag?.ToString());)。

MessageBox已显示,但内容始终为空。

结果: 结果

我如何绑定到文本框?

我不知道为什么你必须那样绑定它。 一种替代方法是绑定到实现INotifyPropertyChanged的属性(此处为: MyText ),然后将DataContext传递给菜单,如下所示:

 <Button x:Name="Button1" Content="Test" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
            <Button.ContextMenu>
                <ContextMenu Placement="Bottom"  DataContext="{Binding Path=PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
                    <MenuItem>
                        <MenuItem.Header>
                            <Grid Height="25" MinWidth="153">
                                <Label Content="Label1" Width="86" HorizontalAlignment="Left" VerticalContentAlignment="Center"/>
                                <TextBox Name="TextBox1" Text="{Binding Path=MyText}"
                                         VerticalContentAlignment="Center" Margin="91,0,0,0"/>
                            </Grid>
                        </MenuItem.Header>
                    </MenuItem>
                </ContextMenu>
            </Button.ContextMenu>
        </Button>

然后不要在Click事件上进行中继以完全获取TextBox值。

如果您想知道绑定为什么不起作用,那是因为MenuItem在其Namescope找不到名为TextBox1的对象。 如果你必须(名称范围是有点棘手),你可以让它通过创建一个新的工作名称范围为你的MenuItem ,并为注册名称TextBox

NameScope.SetNameScope(mi1, new NameScope());
mi1.RegisterName("TextBox1", TextBox1);

其中mi1MenuItem的名称,则绑定将起作用:

<Button x:Name="Button1" Content="Test" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
    <Button.ContextMenu>
        <ContextMenu Placement="Bottom">
            <MenuItem Tag="{Binding ElementName=TextBox1, Path=Text}" Click="MessageBox_ShowTag" Name="mi1">
                <MenuItem.Header>
                    <Grid Height="25" MinWidth="153">
                        <Label Content="Label1" Width="86" HorizontalAlignment="Left" VerticalContentAlignment="Center"/>
                        <TextBox Name="TextBox1" VerticalContentAlignment="Center" Margin="91,0,0,0"/>
                    </Grid>
                </MenuItem.Header>
            </MenuItem>
        </ContextMenu>
    </Button.ContextMenu>
</Button>

另外,请尽可能避免使用x:Name 它可能会导致一些令人讨厌的内存泄漏 使用名称代替。

尝试通过RelativeSource绑定:

<TextBox x:Name="TextBox1" Text="{Binding Path=Tag, RelativeSource={RelativeSource AncestorType={x:Type MenuItem}}}" VerticalContentAlignment="Center" Margin="91,0,0,0"/>

就像评论中提到的那样,对于您要解决的实际问题可能会有更好的解决方案。

但是无论如何,如果您想解决特定问题,可以使用x:Reference代替ElementName来解决,如下所示:

<MenuItem Tag="{Binding Source={x:Reference TextBox1}, Path=Text}"/>

ElementName不起作用,因为VisualTree不同。 如果有兴趣,请在此处进一步阅读-ElementName v / sx:Reference

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM