[英]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);
其中mi1
是MenuItem
的名称,则绑定将起作用:
<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.