2012-04-11 147 views
1

我已经创建了一个基于扩展类的定制控件的自定义WPF控件:如何允许宽度=“自动”,在

public partial class HideableExpander : Expander 
{ 
    public new double Height 
    { 
     get 
     { 
      if (Visibility== System.Windows.Visibility.Hidden) 
      { 
       return 0; 
      } 
      return base.Height; 
     } 
     set 
     { 
      base.Height = value; 
     } 
    } 

    public new double Width 
    { 
     get 
     { 
      if (Visibility == System.Windows.Visibility.Hidden) 
      { 
       return 0; 
      } 
      return base.Width; 
     } 
     set 
     { 
      base.Width = value; 
     } 
    } 

    public new Thickness Margin 
    { 
     get 
     { 
      if (Visibility== System.Windows.Visibility.Hidden) 
      { 
       return new Thickness(); 
      } 
      return base.Margin; 
     } 
     set 
     { 
      base.Margin = value; 
     } 
    } 

    public HideableExpander() 
    { 

     this.InitializeComponent(); 

    } 
} 

XAML:

<Expander 
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" 
mc:Ignorable="d" 
x:Class="leartWPF.HideableExpander" 
x:Name="UserControl" 
d:DesignWidth="640" d:DesignHeight="480"> 

<Grid x:Name="LayoutRoot"/> 
</Expander> 

现在,当我尝试与WIDTH =“自动”属性中使用它:

  <local:HideableExpander Header="{Binding Expander1Name, ElementName=Window}" Margin="10" Width="Auto" Background="#00F19494" VerticalAlignment="Top" > 
       <WrapPanel Height="Auto" Margin="0" Width="Auto" > 
         <TextBlock Text="Please, enter the name of this expander:  " VerticalAlignment="Center"/> 
         <TextBox Width="150" Text="{Binding Expander1Name, ElementName=Window, Mode=TwoWay, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" Background="#FFF5EECC"/> 
       </WrapPanel> 
      </local:HideableExpander> 

我得到有关无法转换“自动”双例外:

Unhandled Exception: System.Windows.Markup.XamlParseException: 'Provide value on 'System.Windows.Baml2006.TypeConverterMarkupExtension' threw an exception.' Line number '10' and line position '8'. ---> System.Exception: Auto is not a valid value for Double. ---> System.FormatException: Input string was not in a correct format. 
    at System.Number.ParseDouble(String value, NumberStyles options, NumberFormatInfo numfmt) 
    at System.Double.Parse(String s, NumberStyles style, IFormatProvider provider) 
    at System.ComponentModel.DoubleConverter.FromString(String value, NumberFormatInfo formatInfo) 
    at System.ComponentModel.BaseNumberConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value) 
    --- End of inner exception stack trace --- 
    at System.ComponentModel.BaseNumberConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value) 
    at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CallProvideValue(MarkupExtension me, IServiceProvider serviceProvider) 
    --- End of inner exception stack trace --- 
    at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri) 
    at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri) 
    at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream) 
    at System.Windows.Application.LoadBamlStreamWithSyncInfo(Stream stream, ParserContext pc) 
    at System.Windows.Application.LoadComponent(Uri resourceLocator, Boolean bSkipJournaledProperties) 
    at System.Windows.Application.DoStartup() 
    at System.Windows.Application.<.ctor>b__1(Object unused) 
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) 
    at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler) 
    at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Int32 numArgs, Delegate catchHandler) 
    at System.Windows.Threading.DispatcherOperation.InvokeImpl() 
    at System.Threading.ExecutionContext.runTryCode(Object userData) 
    at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Windows.Threading.DispatcherOperation.Invoke() 
    at System.Windows.Threading.Dispatcher.ProcessQueue() 
    at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) 
    at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) 
    at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) 
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) 
    at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler) 
    at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Int32 numArgs, Delegate catchHandler) 
    at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) 
    at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) 
    at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg) 
    at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame) 
    at System.Windows.Application.RunInternal(Window window) 
    at System.Windows.Application.Run() 
    at leartWPF.App.Main() in d:\Users\menkaur\Documents\Expression\Blend 4\Projects\leartWPF\leartWPF\obj\Debug\App.g.cs:line 0 

我应该怎么做才能够接受Auto作为一个值?

+1

那么设置Visibility = Collapsed是什么问题? – Phil 2012-04-11 17:49:30

+0

酷!谢谢。实际上更好 – 2012-04-11 18:04:06

回答

4

尝试增加以下属性,我认为应该帮助,当然,“新”隐藏父母的宽度......

[TypeConverterAttribute(typeof(LengthConverter))] 
public new double Width 
{ 
    ......your getter and setter 

// 编辑 每个评论:“什么是吸气剂和二流体?

//getter and setter sample(grabbing them from the question) 
    get 
    { 
     if (Visibility == System.Windows.Visibility.Hidden) 
     { 
      return 0; 
     } 
     return base.Width; 
    } 
    set 
    { 
     base.Width = value; 
    } 
} 
+1

对不起,对于我们这些新来WPF的人来说,你能举一个例子来说明getter和setter的内容吗?他们如何使用这个? – 2013-12-06 15:51:52

+0

get/set是访问者的暴露财产,认为他们读/写到你的班级中的一些私人领域。原因 - 封装一个私有变量,状态,控制。你不希望你的类的用户直接访问它,也许你可以在它们上添加一些逻辑,比如对get进行解析,初始化或格式化,或者对set进行相同的标记验证或事件。在这个问题中,情况正是如此,他们没有直接暴露base.Width,但是如果Window被隐藏,则逻辑宽度被返回为零。希望它是有道理的... – 2013-12-07 00:43:34

+0

我理解getters和setter的概念。我要求提供一个完整的例子,说明他们内部的代码特别适合这种情况。注意我的问题不是“什么是吸气剂和二流体?”。这是“你能举一个例子,说明吸气和吸气器的内容。”你提供的是哪个! :) 谢谢! – 2014-01-02 16:51:08

相关问题