TextBoxPopupBehavior控件
<h2 id="功能说明">功能说明</h2><p>一个用于 WPF TextBox 的附加行为,实现 TextBox 与 Popup 控件的联动效果:</p>
<ol>
<li>
<p><strong>自动弹出/关闭</strong>:</p>
<ul>
<li>TextBox 获得焦点时自动打开关联的 Popup</li>
<li>TextBox 失去焦点时自动关闭关联的 Popup</li>
</ul>
</li>
<li>
<p><strong>点击外部关闭</strong>:</p>
<ul>
<li>点击 TextBox 和 Popup 外部区域时关闭 Popup</li>
</ul>
</li>
<li>
<p><strong>焦点状态处理</strong>:</p>
<ul>
<li>解决 TextBox 保持焦点但 Popup 关闭后的重新触发问题</li>
</ul>
</li>
</ol>
<h2 id="核心代码解析">核心代码解析</h2>
<pre><code class="language-csharp"> // 解决在 TextBox 外其他地方点击时,仅关闭 Popup,但是 TextBox 还是 Focused 状态,导致再点击进来时不会触发弹出 Popup
private void AssociatedObject_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) {
if (AssociatedObject?.IsFocused == true && Popup != null && !Popup.IsOpen) {
Popup.IsOpen = true;
}
}
private void Window_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e) {
if (Popup == null || !Popup.IsOpen || AssociatedObject == null || _parentWindow == null) { return; }
Point position = e.GetPosition(null);
Rect textBoxRect = new Rect(AssociatedObject.TranslatePoint(new Point(0, 0), _parentWindow), AssociatedObject.RenderSize);
Rect popupRect = new Rect(Popup.TranslatePoint(new Point(0, 0), _parentWindow), Popup.RenderSize);
if (!textBoxRect.Contains(position) && !popupRect.Contains(position)) {
Popup.SetCurrentValue(Popup.IsOpenProperty, false);
}
}
</code></pre>
<h2 id="使用方法">使用方法</h2>
<pre><code class="language-xml"><TextBox x:Name="SearchBox"
Width="400"
Height="30"
Text="{Binding ElementName=list, Path=SelectedItem.Content}">
<hc:Interaction.Behaviors>
<controls:TextBoxPopupBehavior Popup="{Binding ElementName=SuggestionsPopup}" />
</hc:Interaction.Behaviors>
</TextBox>
<Popup x:Name="SuggestionsPopup"
Placement="Bottom"
PlacementTarget="{Binding ElementName=SearchBox}"
StaysOpen="True">
<Border Background="White"
BorderBrush="Gray"
BorderThickness="1">
<ListBox x:Name="list"
Width="200"
Height="150">
<ListBoxItem>选项1</ListBoxItem>
<ListBoxItem>选项2</ListBoxItem>
<ListBoxItem>选项3</ListBoxItem>
</ListBox>
</Border>
</Popup>
</code></pre>
<h2 id="注意事项">注意事项</h2>
<ul>
<li>确保 Popup 的 PlacementTarget 正确绑定</li>
<li>在 MVVM 模式下可通过绑定设置 Popup 属性</li>
<li>控件卸载时会自动清理事件监听</li>
</ul>
</div>
<div id="MySignature" role="contentinfo">
<div>
<hr style="height: 2px; border: none; border-top: 2px groove skyblue">
</div>
<div style="text-align: center">
<img src="https://img2024.cnblogs.com/blog/335284/202604/335284-20260402200630931-853910823.jpg"><br>
<span>欢迎您扫一扫上面的微信公众号, 订阅我的博客!</span><br><br>
</div>
<div>
<strong>文章作者:</strong><span style="line-height: 1.5">Memento</span><br>
<strong>博客地址:</strong><span style="color: #337FE5">http://www.cnblogs.com/Memento/</span><br>
<strong>版权声明:</strong><span style="line-height: 1.5">Memento所有文章遵循</span><span style="color: #337FE5">创作共用版权协议</span><span style="line-height: 1.5">,要求</span><strong>署名、非商业、保持一致</strong><span style="line-height: 1.5">。在满足</span><span style="color: #337FE5">创作共用版权协议</span><span style="line-height: 1.5">的基础上可以转载,但请以超链接形式注明出处。</span>
</div>
<div>
<hr style="height: 2px; border: none; border-top: 2px groove skyblue">
</div><br><br>
来源:https://www.cnblogs.com/memento/p/18993294
頁:
[1]