在 FlowDocument 中选择 WPF UIElement

发布于 2024-09-26 13:16:28 字数 506 浏览 7 评论 0原文

我有一个 FlowDocument(在 RichTextBox 内),其中包含 UIElement 控件,例如 CheckBoxes。我需要用户能够单击 CheckBox 来选择它来更改控件属性,例如标签、背景颜色等。

我遇到的问题是,当我单击它时,它只会检查,或者如您所料,取消选中 CheckBox。如何让 CheckBox 在单击时显示自身周围的边框而不更改选中的值。将 IsEnabled 属性设置为 false 意味着我根本无法访问该控件,它无法被识别。

我想我想要实现的最简单的解释类似于 Expression Blend 或 Visual Studio 视觉设计器。当用户单击 CheckBox 时,它会被选中,而不是切换选中的值。

我尝试过到处寻找这个,但不知道该往哪个方向继续。任何帮助将不胜感激。

I have a FlowDocument (inside a RichTextBox) that contains UIElement controls such as CheckBoxes. I need the user to be able to click on the CheckBox to select it to change the controls properties such as label, background color etc.

The problem I have is that when I click it it only checks, or unchecks the CheckBox as you would expect. How would I have the CheckBox display a border around itself when clicked on and not change the checked value. Making the IsEnabled property false means that I can't even access the control at all, it is not recognised.

I guess the simplest explanation of what I am trying to achieve is similar to Expression Blend, or Visual Studio visual designer. When the user clicks a CheckBox it gets selected, rather than the checked value toggling.

I have tried searching all over for this but don't know what direction to proceed. Any help would be appreciated.

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

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

发布评论

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

评论(1

阳光下的泡沫是彩色的 2024-10-03 13:16:29

这个答案并不令人满意,但除了构建自定义 ControlTemplate 之外,这是最简单的(虽然可能是最丑陋的)。

假设我们有一个名为“eins”的 CheckBox,我们将使用 3 个事件来确定其状态:

public void eins_Click(object sender, RoutedEventArgs e)
    {
        var _sender = sender as CheckBox;
        if (_sender.Tag == null || _sender.Tag.ToString() != "pressedOnce")
        {
            _sender.Tag = "pressedOnce";
            _sender.IsChecked = false;


            testStack.Children.Remove(_sender);

            Border border = new Border()
            {
                BorderThickness = new Thickness(2),
                BorderBrush = new SolidColorBrush(Colors.Cyan),
            };
            border.Child = _sender;
            testStack.Children.Insert(0, border);
        }

        else
        {
            _sender.IsChecked = true;
        }
    }

    private void eins_LostFocus(object sender, RoutedEventArgs e)
    {
        var _sender = sender as CheckBox;
        _sender.Tag = "";
        var border = _sender.Parent as Border;
        border.Child = null;
        testStack.Children.Remove(border);
        testStack.Children.Insert(0,_sender);
    }

    private void eins_Checked(object sender, RoutedEventArgs e)
    {
        DispatcherTimer timer = new DispatcherTimer()
        { 
           Interval = new TimeSpan(0,0,1) 
        };
        timer.Tick += new EventHandler(timer_Tick);
        timer.Start();
    }

    void timer_Tick(object sender, EventArgs e)
    {
        if (eins.IsChecked == true)
        { 
            //do whatever you want to do
        }
    }

现在这更多的是一个解决方案,并且有几个缺点:

1)您需要确保复选框的选中时间永远不会超过 1 秒,否则您需要提高 TimeSpan
2)你总是需要知道复选框的实际父控件是什么类型
3)您需要完成错误检查,这可能无法开箱即用
4)这并不是真正为了性能而构建的

This answer is not satisfying, but besides building a custom ControlTemplate, this was the easiest (while probably ugliest) to do.

Assuming we have a CheckBox by the name of "eins" we would use 3 events to determine its states:

public void eins_Click(object sender, RoutedEventArgs e)
    {
        var _sender = sender as CheckBox;
        if (_sender.Tag == null || _sender.Tag.ToString() != "pressedOnce")
        {
            _sender.Tag = "pressedOnce";
            _sender.IsChecked = false;


            testStack.Children.Remove(_sender);

            Border border = new Border()
            {
                BorderThickness = new Thickness(2),
                BorderBrush = new SolidColorBrush(Colors.Cyan),
            };
            border.Child = _sender;
            testStack.Children.Insert(0, border);
        }

        else
        {
            _sender.IsChecked = true;
        }
    }

    private void eins_LostFocus(object sender, RoutedEventArgs e)
    {
        var _sender = sender as CheckBox;
        _sender.Tag = "";
        var border = _sender.Parent as Border;
        border.Child = null;
        testStack.Children.Remove(border);
        testStack.Children.Insert(0,_sender);
    }

    private void eins_Checked(object sender, RoutedEventArgs e)
    {
        DispatcherTimer timer = new DispatcherTimer()
        { 
           Interval = new TimeSpan(0,0,1) 
        };
        timer.Tick += new EventHandler(timer_Tick);
        timer.Start();
    }

    void timer_Tick(object sender, EventArgs e)
    {
        if (eins.IsChecked == true)
        { 
            //do whatever you want to do
        }
    }

Now this is more of a workaround solution and has several drawbacks:

1) you need to be sure the box is never checked for longer than 1 sec, else you need to raise the TimeSpan
2) You always need to know what type of Control is the Checkbox's actual parent
3) You would need to finish checking for bugs, this probably won't work out of the box
4) This is not really build for performance

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