草庐IT

WPF矩形在更改属性时会起作用

程序员大本营 2024-05-28 原文

情况:

我有一个自定义的WPF USERCORTROL,应该像大多数移动操作系统的切换按钮一样。

单击一次时,它应该从一个状态变为另一种状态。

我的问题 有时,只是不按我想要的方式工作。矩形消失,或者红色/灰色背景矩形不会涂色。

否则它们将被绘制两次左右。

我的代码 我有一个网格:在背景矩形中有一个网格,在不同的列中,有3个“ selectRectangles”。

<UserControl x:Class="test.StatusControl"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"          xmlns:d="http://schemas.microsoft.com/expression/blend/2008"          xmlns:local="clr-namespace:test"         mc:Ignorable="d"          d:DesignHeight="20" d:DesignWidth="80">    <UserControl.Resources>        <!-- my dummy values -->    <SolidColorBrush x:Key="BackgroundBrush" Color="DarkGray" />    <SolidColorBrush x:Key="TSBackgroundBrush" Color="Gray" />    <SolidColorBrush x:Key="TSBarBrush" Color="LightGreen" />    <SolidColorBrush x:Key="AccentColorBrush1" Color="Khaki" />        <Style TargetType="Rectangle" x:Key="SliderRectangleStyle">            <Setter Property="Stroke" Value="{DynamicResource BackgroundBrush}" />            <Setter Property="Fill" Value="{DynamicResource TSBarBrush}" />            <Style.Triggers>                <DataTrigger Binding="{Binding Status, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="0">                    <Setter Property="Grid.Column" Value="0" />                </DataTrigger>                <DataTrigger Binding="{Binding Status, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="1">                    <Setter Property="Grid.Column" Value="2" />                </DataTrigger>                <DataTrigger Binding="{Binding Status, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="2">                    <Setter Property="Grid.Column" Value="4" />                </DataTrigger>            </Style.Triggers>        </Style>        <Style TargetType="Rectangle" x:Key="LeftFillRectangleStyle">            <Setter Property="Stroke" Value="{DynamicResource BackgroundBrush}" />            <Setter Property="Fill" Value="{DynamicResource AccentColorBrush1}" />            <Setter Property="Margin" Value="2,2,0,2" />            <Style.Triggers>                <DataTrigger Binding="{Binding Status, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="0">                    <Setter Property="Visibility" Value="Collapsed" />                </DataTrigger>                <DataTrigger Binding="{Binding Status, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="1">                    <Setter Property="Grid.ColumnSpan" Value="2" />                </DataTrigger>                <DataTrigger Binding="{Binding Status, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="2">                    <Setter Property="Grid.ColumnSpan" Value="4" />                </DataTrigger>            </Style.Triggers>        </Style>        <Style x:Key="TextLabelStyle" TargetType="TextBlock">            <Style.Triggers>                <DataTrigger Binding="{Binding Status, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="0">                    <Setter Property="Text" Value="Aus" />                </DataTrigger>                <DataTrigger Binding="{Binding Status, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="1">                    <Setter Property="Text" Value="Client" />                </DataTrigger>                <DataTrigger Binding="{Binding Status, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="2">                    <Setter Property="Text" Value="Finance Dept." />                </DataTrigger>            </Style.Triggers>        </Style>    </UserControl.Resources>    <Grid>        <Grid.ColumnDefinitions>            <ColumnDefinition Width="10"/>            <ColumnDefinition Width="10"/>            <ColumnDefinition Width="10"/>            <ColumnDefinition Width="10"/>            <ColumnDefinition Width="10"/>            <ColumnDefinition Width="auto"/>        </Grid.ColumnDefinitions>        <Rectangle         Margin="5,2,5,2"         Grid.Row="0"         Grid.Column="0"         Grid.ColumnSpan="5"         Fill="{DynamicResource BackgroundBrush}"         Stroke="{DynamicResource TSBackgroundBrush}"        />        <TextBlock         Grid.Row="0"         Grid.Column="5"         Style="{StaticResource TextLabelStyle}"        Margin="4,0,4,0"         />        <Rectangle Style="{StaticResource LeftFillRectangleStyle}" />        <Rectangle Style="{StaticResource SliderRectangleStyle}" />        <!-- Overlay the slider area with three equal click areas -->        <Grid Grid.Column="0" Grid.ColumnSpan="5">            <Grid.ColumnDefinitions>                <ColumnDefinition Width="*" />                <ColumnDefinition Width="*" />                <ColumnDefinition Width="*" />            </Grid.ColumnDefinitions>            <Grid.Resources>                <!--             Because this style has no x:Key, it will apply to all Rectangles in this Grid             -->                <Style TargetType="Rectangle" >                    <!--                 Uncomment these setters to make sure the clickable areas are where                 they should be.                -->                    <!--                <Setter Property="Stroke" Value="Red" />                <Setter Property="StrokeThickness" Value="1" />               -->                    <Setter Property="Fill" Value="Transparent" />                    <EventSetter Event="PreviewMouseDown" Handler="StatusSelect_PreviewMouseDown" />                </Style>            </Grid.Resources>            <Rectangle Grid.Column="0" />            <Rectangle Grid.Column="1" />            <Rectangle Grid.Column="2" />        </Grid>    </Grid></UserControl>

由于移动一个矩形,我将可见性设置为隐藏/可见的,恰好提出了同样的问题。

  using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;namespace test{    /// <summary>    /// Interaktionslogik für StatusControl.xaml    /// </summary>    public partial class StatusControl : UserControl    {        public StatusControl()        {            InitializeComponent();        }        #region Status Property        public int Status {            get { return (int)GetValue(StatusProperty); }            set { SetValue(StatusProperty, value); }        }        public static readonly DependencyProperty StatusProperty =            DependencyProperty.Register(nameof(Status), typeof(int), typeof(StatusControl),new PropertyMetadata(0));        #endregion Status Property        private void StatusSelect_PreviewMouseDown(object sender, MouseButtonEventArgs e)        {            Status = Grid.GetColumn(sender as UIElement);        }    }}

主窗口XAML:

<Window x:Class="test.MainWindow"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"    xmlns:local="clr-namespace:test"    mc:Ignorable="d"    Title="MainWindow" Height="350" Width="525"><Grid>    <StackPanel>        <local:StatusControl Status="1"/>        <local:StatusControl Status="2"/>        <local:StatusControl Status="3"/>        <Slider x:Name="TestSlider" Minimum="0" Maximum="2" Width="200"/>        <local:StatusControl Status="{Binding Value, ElementName=TestSlider}"/>    </StackPanel></Grid>

我曾经尝试过的解决方案 看来他们只是没有更新。我尝试调用this.updatelayout(),但这无济于事。有时,几秒钟后,它也会重新刷新。有时不...

感谢您阅读/帮助!

看答案

首先,让我们给您的状态控制 Status 依赖性属性。我不知道您的控制权或什么 status 您拥有的可变,所以我只称呼我的控制 StatusControl。我认为您可能会更好 Status 而不是int(Good, Indifferent, Bad, 或者 Error, Warning, Success 或类似的东西)。但是我会坚持你的 int 目前。

public partial class StatusControl : UserControl{    public StatusControl()    {        InitializeComponent();    }    #region Status Property    public int Status    {        get { return (int)GetValue(StatusProperty); }        set { SetValue(StatusProperty, value); }    }    public static readonly DependencyProperty StatusProperty =        DependencyProperty.Register(nameof(Status), typeof(int), typeof(StatusControl),            new PropertyMetadata(0));    #endregion Status Property    private void StatusSelect_PreviewMouseDown(object sender, MouseButtonEventArgs e)    {        Status = Grid.GetColumn(sender as UIElement);    }}

然后 Status 属性通过 Triggers 在两个矩形样式中。

  • SliderRectangleStyle 动态重新定位代表滑块的单个矩形。
  • LeftFillRectangleStyle 动态显示/生皮,并调整一个矩形,该矩形填充滑块的重音区域。

您可能需要稍微微调利润,以获取最初的确切比例;当我撕开您的原始XAML时,我非常随意。

<UserControl.Resources>    <!-- my dummy values -->    <!--     <SolidColorBrush x:Key="BackgroundBrush" Color="DarkGray" />    <SolidColorBrush x:Key="TSBackgroundBrush" Color="Gray" />    <SolidColorBrush x:Key="TSBarBrush" Color="LightGreen" />    <SolidColorBrush x:Key="AccentColorBrush1" Color="Khaki" />    -->    <Style TargetType="Rectangle" x:Key="SliderRectangleStyle">        <Setter Property="Stroke" Value="{DynamicResource BackgroundBrush}" />        <Setter Property="Fill" Value="{DynamicResource TSBarBrush}" />        <Style.Triggers>            <DataTrigger Binding="{Binding Status, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="0">                <Setter Property="Grid.Column" Value="0" />            </DataTrigger>            <DataTrigger Binding="{Binding Status, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="1">                <Setter Property="Grid.Column" Value="2" />            </DataTrigger>            <DataTrigger Binding="{Binding Status, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="2">                <Setter Property="Grid.Column" Value="4" />            </DataTrigger>        </Style.Triggers>    </Style>    <Style TargetType="Rectangle" x:Key="LeftFillRectangleStyle">        <Setter Property="Stroke" Value="{DynamicResource BackgroundBrush}" />        <Setter Property="Fill" Value="{DynamicResource AccentColorBrush1}" />        <Setter Property="Margin" Value="2,2,0,2" />        <Style.Triggers>            <DataTrigger Binding="{Binding Status, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="0">                <Setter Property="Visibility" Value="Collapsed" />            </DataTrigger>            <DataTrigger Binding="{Binding Status, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="1">                <Setter Property="Grid.ColumnSpan" Value="2" />            </DataTrigger>            <DataTrigger Binding="{Binding Status, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="2">                <Setter Property="Grid.ColumnSpan" Value="4" />            </DataTrigger>        </Style.Triggers>    </Style>    <Style x:Key="TextLabelStyle" TargetType="TextBlock">        <Style.Triggers>            <DataTrigger Binding="{Binding Status, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="0">                <Setter Property="Text" Value="Aus" />            </DataTrigger>            <DataTrigger Binding="{Binding Status, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="1">                <Setter Property="Text" Value="Client" />            </DataTrigger>            <DataTrigger Binding="{Binding Status, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="2">                <Setter Property="Text" Value="Finance Dept." />            </DataTrigger>        </Style.Triggers>    </Style></UserControl.Resources><Grid>    <Grid.ColumnDefinitions>        <ColumnDefinition Width="10"/>        <ColumnDefinition Width="10"/>        <ColumnDefinition Width="10"/>        <ColumnDefinition Width="10"/>        <ColumnDefinition Width="10"/>        <ColumnDefinition Width="auto"/>    </Grid.ColumnDefinitions>    <Rectangle         Margin="5,2,5,2"         Grid.Row="0"         Grid.Column="0"         Grid.ColumnSpan="5"         Fill="{DynamicResource BackgroundBrush}"         Stroke="{DynamicResource TSBackgroundBrush}"        />    <TextBlock         Grid.Row="0"         Grid.Column="5"         Style="{StaticResource TextLabelStyle}"        Margin="4,0,4,0"         />    <Rectangle Style="{StaticResource LeftFillRectangleStyle}" />    <Rectangle Style="{StaticResource SliderRectangleStyle}" />    <!-- Overlay the slider area with three equal click areas -->    <Grid Grid.Column="0" Grid.ColumnSpan="5">        <Grid.ColumnDefinitions>            <ColumnDefinition Width="*" />            <ColumnDefinition Width="*" />            <ColumnDefinition Width="*" />        </Grid.ColumnDefinitions>        <Grid.Resources>            <!--             Because this style has no x:Key, it will apply to all Rectangles in this Grid             -->            <Style TargetType="Rectangle" >                <!--                 Uncomment these setters to make sure the clickable areas are where                 they should be.                -->                <!--                <Setter Property="Stroke" Value="Red" />                <Setter Property="StrokeThickness" Value="1" />                -->                <Setter Property="Fill" Value="Transparent" />                <EventSetter Event="PreviewMouseDown" Handler="StatusSelect_PreviewMouseDown" />            </Style>        </Grid.Resources>        <Rectangle Grid.Column="0" />        <Rectangle Grid.Column="1" />        <Rectangle Grid.Column="2" />    </Grid></Grid>

有关WPF矩形在更改属性时会起作用的更多相关文章

  1. ruby-on-rails - Ruby on Rails 迁移,将表更改为 MyISAM - 2

    如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设

  2. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  3. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  4. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

  5. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  6. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  7. ruby - Capistrano 3 在任务中更改 ssh_options - 2

    我尝试使用不同的ssh_options在同一阶段运行capistranov.3任务。我的production.rb说:set:stage,:productionset:user,'deploy'set:ssh_options,{user:'deploy'}通过此配置,capistrano与用户deploy连接,这对于其余的任务是正确的。但是我需要将它连接到服务器中配置良好的an_other_user以完成一项特定任务。然后我的食谱说:...taskswithoriginaluser...task:my_task_with_an_other_userdoset:user,'an_othe

  8. ruby - Nokogiri 剥离所有属性 - 2

    我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog

  9. ruby-on-rails - Rails 模型——非持久类成员或属性? - 2

    对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs

  10. ruby - 更改 ActiveRecord 中对象的类 - 2

    假设我有一个FireNinja我的数据库中的对象,使用单表继承存储。后来才知道他真的是WaterNinja.将他更改为不同的子类的最干净的方法是什么?更好的是,我很想创建一个新的WaterNinja对象并替换旧的FireNinja在数据库中,保留ID。编辑我知道如何创建新的WaterNinja来self现有FireNinja的对象,我也知道我可以删除旧的并保存新的。我想做的是改变现有项目的类别。我是通过创建一个新对象并执行一些ActiveRecord魔法来替换行,还是通过对对象本身做一些疯狂的事情,或者甚至通过删除它并使用相同的ID重新插入来做到这一点,这是问题的一部分。

随机推荐