在menuitem的标题中绑定ElementName

时间:2016-01-26 13:53:50

标签: c# wpf

我尝试将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>

单击menuitem时,调用MessageBox以在MenuItem中显示标记 (MessageBox.Show((发送者为MenuItem).Tag?.ToString());)

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

结果: Result

如何绑定到文本框?

3 个答案:

答案 0 :(得分:1)

我不知道为什么你必须这样绑定它。另一种方法是绑定到实现MyText的属性(此处为:INotifyPropertyChanged),然后将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无法在其TextBox1中找到名为Namescope的对象。如果你必须(名称范围有点棘手),你可以通过为MenuItem创建一个新的Namescope并注册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:NameIt can cause some nasty memory leaks。请改用名称。

答案 1 :(得分:0)

尝试通过RelativeSource绑定:

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

答案 2 :(得分:0)

如同评论中提到的那样,可以更好地解决您试图解决的实际问题。

但无论如何,如果你想要针对特定​​问题的解决方案,可以使用x:Reference代替ElementName来解决这个问题:

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

ElementName无效,因为VisualTree不同。如果有兴趣在这里进一步阅读 - ElementName v/s x:Reference