Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# wpf矩形在更改属性时行为怪异_C#_Wpf - Fatal编程技术网

C# wpf矩形在更改属性时行为怪异

C# wpf矩形在更改属性时行为怪异,c#,wpf,C#,Wpf,情况: 我有一个自定义的WPF用户控件,它应该类似于大多数移动操作系统中的切换按钮。 当点击它一次时,它应该从一种状态变为另一种状态 我的问题 有时候我的工作方式不符合我的要求。要么矩形消失,要么红色/灰色背景矩形不着色。 否则他们将被画两次左右 我的代码 我有一个网格: 在中,有一个网格用于背景矩形 3个“选择矩形”在不同的列中 <UserControl x:Class="test.StatusControl" xmlns="http://schemas.micro

情况

我有一个自定义的WPF用户控件,它应该类似于大多数移动操作系统中的切换按钮。

当点击它一次时,它应该从一种状态变为另一种状态

我的问题 有时候我的工作方式不符合我的要求。要么矩形消失,要么红色/灰色背景矩形不着色。

否则他们将被画两次左右

我的代码 我有一个网格: 在中,有一个网格用于背景矩形 3个“选择矩形”在不同的列中

<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>

我将可见性设置为hidden/visible(隐藏/可见),因为移动一个矩形时,碰巧遇到了相同的问题

  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);
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Navigation;
使用System.Windows.Shapes;
名称空间测试
{
/// 
///Interaktionslogik für StatusControl.xaml
/// 
公共部分类StatusControl:UserControl
{
公共状态控制()
{
初始化组件();
}
#区域状态属性
公共int状态{
获取{return(int)GetValue(StatusProperty);}
set{SetValue(StatusProperty,value);}
}
公共静态只读DependencyProperty StatusProperty=
DependencyProperty.Register(nameof(Status)、typeof(int)、typeof(StatusControl)、newpropertyMetadata(0));
#endregion状态属性
私有无效状态选择_预览鼠标向下(对象发送器,鼠标按钮ventargs e)
{
Status=Grid.GetColumn(发送方作为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>

我尝试过的解决方案 看起来他们只是不更新。我尝试调用此.UpdateLayout(),但没有效果。有时,他们也会在几秒钟后重新绘制自己,然后就没事了。有时不是


谢谢你的阅读/帮助

首先,让我们为状态控件提供一个
status
dependency属性。我不知道你的控件被调用了什么,也不知道你的
status
变量是关于什么的,所以我只调用我的控件
StatusControl
。我认为最好使用
状态的枚举,而不是int(
好的
不相关的
坏的
,或
错误
警告
成功
或诸如此类的东西)。但我现在还是坚持你的
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
属性通过两个矩形样式中的
触发器驱动用户控件中的更改

  • 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>


我不使用3个矩形,而是使用1个矩形并设置顶部/左侧属性的动画,使其从一个位置平滑地滑动到下一个位置。你的问题是C代码。你所做的每件事都可以而且应该用XAML来完成。是的,我只有一个矩形。但它也有同样的问题,甚至更糟。好吧,我会调查的。谢谢你的提示你知道我可以通读的消息来源吗?非常感谢你的回答!我会测试一下,然后回来标记你的订单