gpt4 book ai didi

silverlight - 单击以编辑控件 - 怎么做?

转载 作者:行者123 更新时间:2023-12-02 00:37:21 28 4
gpt4 key购买 nike

我正在使用 Silverlight 2.0 Unleashed + Silverlight 4.0 Unleashed 学习 Silverlight,好吧,我只是在玩弄它:-)

作为其中的一部分,我正在尝试开发一个应该非常简单的内容控件:一个您可以通过单击来编辑的标签。

我的灵感来自另一个 SO 问题 ( Click-to-edit in Silverlight ),但我遇到了一些与 Silverlight 新手相关的问题。 :)

我会先发布代码,然后再发布我的问题。

这是我的 XAML:

<ContentControl x:Class="MyTestProject.SilverlightControl1"
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:sdk="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input" xmlns:local="clr-namespace:MyTestProject" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<ContentControl.Resources>
<ControlTemplate x:Key="EditableLabelTextboxTemplate">
<TextBox Name="UCTB" Text="{Binding Text, Mode=TwoWay}" Width="100" Height="25" ></TextBox>
</ControlTemplate>
<ControlTemplate x:Name="LabelTemplate" TargetType="local:SilverlightControl1">
<sdk:Label x:Name="UCLBL" Content="{Binding Text}" />
</ControlTemplate>
<Style TargetType="local:SilverlightControl1">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate x:Name="LabelTemplate2" TargetType="local:SilverlightControl1">
<sdk:Label x:Name="UCLBL" Content="{Binding Text}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ContentControl.Resources>
</ContentControl>

这是我的代码隐藏:

public partial class SilverlightControl1 : ContentControl
{
public string Text { get; set; }

public SilverlightControl1()
{
this.DataContext = this;
Text = "Hello, World!";
this.DefaultStyleKey = typeof(SilverlightControl1);
//Template = this.Resources["LabelTemplate"] as ControlTemplate;
InitializeComponent();
}

public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this.MouseLeftButtonDown += HandleLabelLeftMouseDown;
this.KeyDown += HandleTextboxEnter;
}

public static void HandleTextboxEnter(object sender, KeyEventArgs args)
{
var ctrl = sender as SilverlightControl1;
if (ctrl.Template == ctrl.Resources["EditableLabelTextboxTemplate"])
{
if (args.Key == Key.Enter)
{
ctrl.Template = ctrl.Resources["LabelTemplate"] as ControlTemplate;
}
}
}

public static void HandleLabelLeftMouseDown(object sender, MouseButtonEventArgs args)
{
var editableLabel = sender as SilverlightControl1;
if (editableLabel.Template != editableLabel.Resources["EditableLabelTextboxTemplate"])
{
editableLabel.Template = editableLabel.Resources["EditableLabelTextboxTemplate"] as ControlTemplate;
}
}
}

首先,我必须实例化我的控件的方式非常笨拙和多余。

有 2 个 ControlTemplates(一个标签,一个文本框),但还有一个带有用于初始化的标签的样式。如果我删除它(以及代码隐藏中构造函数中的相应行),即使我也设置了模板,也不会呈现任何内容。一定有更好的方法吗?

我的第二个问题是,当我将控件放入测试项目并使用它时,控件移动?它会从中间的左侧开始作为标签,然后单击它,文本框出现在页面的中央,然后输入标签重新出现在屏幕的左侧?

编辑:第三,一旦我用文本框替换标签,文本框就没有焦点,我不知道如何给它?

最后,现在停止编辑的唯一方法是点击“输入”。理想情况下,我只想在文本框外单击,但使用失去焦点事件(如链接中所建议的)似乎触发得太频繁,我无法使用它?

我希望一些 Silverlight 大师可以帮助我! :-)

哦,如果有人知道我可以使用/查看可用的点击编辑控件,我也将非常感激 :)

提前致谢!

最佳答案

希望我没说错。你需要的是一个文本框,一开始是不可编辑的,但如果你点击它,它将是可编辑的。

为此,我创建了一个继承自 TextBox 的控件(我使用了 vs 模板 TemplatedControl)。我添加了两种状态(编辑和非编辑)和一个矩形,它作为非编辑模式文本的图层(以防止在鼠标悬停时更改鼠标光标)。我也在边界上做了一些作业。例如。在非编辑状态下,边框大小为 0,因此 TextBox 看起来像一个标签。

这是 xaml:

<Style TargetType="local:ClickToEditTextBox">
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Background" Value="#FFFFFFFF"/>
<Setter Property="Foreground" Value="#FF000000"/>
<Setter Property="Padding" Value="2"/>
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFA3AEB9" Offset="0"/>
<GradientStop Color="#FF8399A9" Offset="0.375"/>
<GradientStop Color="#FF718597" Offset="0.375"/>
<GradientStop Color="#FF617584" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:ClickToEditTextBox">
<Grid x:Name="RootElement">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="DisabledVisualElement" Storyboard.TargetProperty="Opacity" To="1" Duration="0"/>
</Storyboard>
</VisualState>
<VisualState x:Name="ReadOnly">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="ReadOnlyVisualElement" Storyboard.TargetProperty="Opacity" To="1" Duration="0" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity" To="1" Duration="0"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity" To="0" Duration="0"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="ValidationStates">
<VisualState x:Name="Valid"/>
<VisualState x:Name="InvalidUnfocused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="InvalidFocused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ValidationErrorElement" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsOpen">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<sys:Boolean>True</sys:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<!-- The new edit states -->
<VisualStateGroup x:Name="EditStates">
<VisualState x:Name="Edit">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="rectangle">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="NotEdit">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderThickness)" Storyboard.TargetName="Border">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Thickness>0</Thickness>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Border" CornerRadius="1" Opacity="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1">
<Grid>
<Border x:Name="ReadOnlyVisualElement" Opacity="0" Background="#5EC9C9C9"/>
<Border x:Name="MouseOverBorder" BorderThickness="1" BorderBrush="Transparent">
<Grid>
<ScrollViewer x:Name="ContentElement" Padding="{TemplateBinding Padding}" BorderThickness="0" IsTabStop="False"/>
<Rectangle x:Name="rectangle" Fill="#02FFFFFF" />
</Grid>
</Border>
</Grid>
</Border>
<Border x:Name="DisabledVisualElement" Background="#A5F7F7F7" BorderBrush="#A5F7F7F7" BorderThickness="{TemplateBinding BorderThickness}" Opacity="0" IsHitTestVisible="False"/>
<Border x:Name="FocusVisualElement" BorderBrush="#FF6DBDD1" BorderThickness="{TemplateBinding BorderThickness}" Margin="1" Opacity="0" IsHitTestVisible="False"/>
<Border x:Name="ValidationErrorElement" BorderThickness="1" CornerRadius="1" BorderBrush="#FFDB000C" Visibility="Collapsed">
<ToolTipService.ToolTip>
<ToolTip x:Name="validationTooltip" Template="{StaticResource ValidationToolTipTemplate}" Placement="Right"
PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}"
DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">
<ToolTip.Triggers>
<EventTrigger RoutedEvent="Canvas.Loaded">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="validationTooltip" Storyboard.TargetProperty="IsHitTestVisible">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<sys:Boolean>true</sys:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ToolTip.Triggers>
</ToolTip>
</ToolTipService.ToolTip>
<Grid Width="12" Height="12" HorizontalAlignment="Right" Margin="1,-4,-4,0" VerticalAlignment="Top" Background="Transparent">
<Path Margin="1,3,0,0" Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z" Fill="#FFDC000C"/>
<Path Margin="1,3,0,0" Data="M 0,0 L2,0 L 8,6 L8,8" Fill="#ffffff"/>
</Grid>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

如您所见,有两个新状态,Edit 和 NotEdit。

因此在后面的代码中,我将控件初始化“发送”到 NotEdit 状态并添加两个处理程序,分别用于 GotFocus 和 LostFocus。

this.GotFocus += ClickToEditTextBox_GotFocus;
this.LostFocus += ClickToEditTextBox_LostFocus;
VisualStateManager.GoToState(this, "NotEdit", false);

处理程序只是“发送”处于定义状态的控件:

void ClickToEditTextBox_LostFocus(object sender, RoutedEventArgs e)
{
VisualStateManager.GoToState(this, "NotEdit", false);
}

void ClickToEditTextBox_GotFocus(object sender, RoutedEventArgs e)
{
VisualStateManager.GoToState(this, "Edit", false);
}

完整的源代码如下:

public class ClickToEditTextBox : TextBox
{
public ClickToEditTextBox()
{
this.DefaultStyleKey = typeof(ClickToEditTextBox);
}

public override void OnApplyTemplate()
{
base.OnApplyTemplate();

this.GotFocus += ClickToEditTextBox_GotFocus;
this.LostFocus += ClickToEditTextBox_LostFocus;

VisualStateManager.GoToState(this, "NotEdit", false);

}

void ClickToEditTextBox_LostFocus(object sender, RoutedEventArgs e)
{
VisualStateManager.GoToState(this, "NotEdit", false);
}

void ClickToEditTextBox_GotFocus(object sender, RoutedEventArgs e)
{
VisualStateManager.GoToState(this, "Edit", false);
}
}

现在您可以在您的用户控件中使用它了:

<SilverlightApplication1:ClickToEditTextBox Text="12345" Width="100" Height="22" />

这只是一个快速实现,因此可以进行一些改进。但我希望,这可以帮助您解决问题。

BR, TJ

关于silverlight - 单击以编辑控件 - 怎么做?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4067455/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com