你能否在Silverlight中覆盖控件模板的一部分

时间:2009-04-23 15:25:35

标签: silverlight

是否可以更改或修改控件模板的特定部分,而无需在xaml中重新创建控件的整个控件模板?

例如,我试图摆脱文本框的边框,因此我可以将带有圆角的基本搜索框放在一起(下面的示例xaml)。将borderthickness设置为0可以正常工作,直到您将鼠标悬停在文本框上并且他们添加到控件中的伪边框闪烁。如果我查看文本框的controltemplate,我甚至可以看到视觉状态已命名,但无法想到如何禁用它。

如果不覆盖TextBox的控件模板,我如何停止Visual State Manager在TextBox上触发鼠标效果?

<Border Background="White" CornerRadius="10" VerticalAlignment="Center" HorizontalAlignment="Center" BorderThickness="3" BorderBrush="#88000000">
    <Grid VerticalAlignment="Center" HorizontalAlignment="Center" Width="200" Margin="5,0,0,0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="16" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Path Height="13" Width="14" Stretch="Fill" Stroke="#FF000000" StrokeThickness="2" Data="M9.5,5 C9.5,7.4852815 7.4852815,9.5 5,9.5 C2.5147185,9.5 0.5,7.4852815 0.5,5 C0.5,2.5147185 2.5147185,0.5 5,0.5 C7.4852815,0.5 9.5,2.5147185 9.5,5 z M8.5,8.4999971 L13.5,12.499997" />
            <TextBox GotFocus="TextBox_GotFocus" Background="Transparent" Grid.Column="1" BorderThickness="0" Text="I am searchtext" Margin="5,0,5,0" HorizontalAlignment="Stretch" />
    </Grid>
</Border>

4 个答案:

答案 0 :(得分:5)

通过继承控件并覆盖OnApplyTemplate,我找到了一种方法。它并不理想,但我认为它比复制整个控件模板更好。以下是创建无边框文本框的示例,通过始终清除故事板,实际上禁用鼠标而不是可视状态:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;

namespace SilverlightTestApplication
{
    public class BorderlessTextBox  : TextBox
    {
        public BorderlessTextBox()
        {
            BorderThickness = new System.Windows.Thickness(0);
        }

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

            //Get the mouse over animation in the control template
            var MouseOverVisualState = GetTemplateChild("MouseOver") as VisualState;

            if (MouseOverVisualState == null)
                return;

            //get rid of the storyboard it uses, so the mouse over does nothing
            MouseOverVisualState.Storyboard = null;
        }
    }
}

答案 1 :(得分:2)

自从我使用XAML以来已经有一段时间了,但不,我不相信你只能修改一块模板。

但是,如果您有IDE,则可以创建当前应用模板的副本,只需修改所需的部分,其余部分保留原样。请参阅this link.

的“如何编辑”部分

答案 2 :(得分:0)

使用XAML阅读器检索每个控件的默认模板,然后复制/粘贴并修改您想要的内容...不是很干净但我认为这是唯一的方法(我正在搜索如何检索此默认模板)

答案 3 :(得分:0)

在WPF中,不确定silverlight这里有一段代码来检索Aero模板,您可以尝试复制/粘贴并更改您想要的内容:

        public Window1()
        {
            InitializeComponent();
            using(FileStream fs = new FileStream("C:/TextBoxTemplate.xaml", FileMode.Create))
            {
                var res = LoadThemeDictionary(typeof(TextBox), "Aero", "NormalColor");
                var buttonRes = res[typeof(TextBox)];
                XamlWriter.Save(buttonRes, fs);
            }
        }

        public static ResourceDictionary LoadThemeDictionary(Type t,
        string themeName, string colorScheme)
        {
            Assembly controlAssembly = t.Assembly;
            AssemblyName themeAssemblyName = controlAssembly.GetName();

            object[] attrs = controlAssembly.GetCustomAttributes(
                    typeof(ThemeInfoAttribute), false);
            if(attrs.Length > 0)
            {
                ThemeInfoAttribute ti = (ThemeInfoAttribute)attrs[0];

                if(ti.ThemeDictionaryLocation ==
                                                         ResourceDictionaryLocation.None)
                {
                    // There are no theme-specific resources.
                    return null;
                }

                if(ti.ThemeDictionaryLocation ==
                                ResourceDictionaryLocation.ExternalAssembly)
                {
                    themeAssemblyName.Name += "." + themeName;
                }
            }

            string relativePackUriForResources = "/" +
                    themeAssemblyName.FullName +
                    ";component/themes/" +
                    themeName + "." +
                    colorScheme + ".xaml";

            Uri resourceLocater = new System.Uri(
                    relativePackUriForResources, System.UriKind.Relative);

            return Application.LoadComponent(resourceLocater)
                                 as ResourceDictionary;
        }

我从未使用Silverlight,但我认为将此模板改编为Silverlight并不需要做很多事情。

来源:Default template in WPF