【问题标题】:wpf how to bind usercontrol propertywpf如何绑定用户控件属性
【发布时间】:2014-11-11 03:03:07
【问题描述】:

您好,我正在尝试绑定用户控件属性,但到目前为止还没有成功。下面是我的代码。

<UserControl x:Class="MyControl"
       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" 
       mc:Ignorable="d" 
       d:DesignHeight="120" d:DesignWidth="120"
       x:Name="uc"
       Background="Transparent">
    <Grid>
        <Viewbox> 
           ......
           <CheckBox Name="Start" Visibility="Hidden" IsChecked="{Binding Path=Animation, ElementName=uc, Mode=TwoWay}"/>
           .......
        </Viewbox>
    </Grid>
</UserControl>

后面的用户控制代码。

  public partial class MyControl: UserControl
  {
    public static readonly DependencyProperty AnimationProperty = DependencyProperty.Register("Animation", typeof(bool), typeof(CircularProgressBar));
    public bool Animation
    {
      get { return (bool)GetValue(AnimationProperty); }
      set 
      {
        SetValue(AnimationProperty, value); 
      }
    }


    public MyControl()
    {
      InitializeComponent();
      //(this.Content as FrameworkElement).DataContext = this;
    }

  }

查看代码

<local:MyControl x:Name="cpb" Animation="{Binding CpbIsEnabled, Mode=TwoWay}"  />

查看模型代码

private bool cpbEnabled;
public bool CpbIsEnabled
{
  get { return cpbEnabled; }
  set { cpbEnabled = value; OnPropertyChanged("CpbIsEnabled");  }
}

public ICommand ShowSelFlagCommand
{
  get
  {
    return showSelFlagCommand ?? (showSelFlagCommand = new DelegateCommand(() =>
    {
      if (CpbIsEnabled) { CpbIsEnabled = false; }
      else { CpbIsEnabled = true; }
    }
    ));
  }
}

我在用户控件代码后面的动画属性设置方法中设置了一个断点。但是当视图模型中的 ICOCommand 执行时,它永远不会到达断点。换句话说,Animation 属性不是由绑定设置的。

谁能告诉我我错过了什么?

谢谢,

【问题讨论】:

  • 动画属性设置方法不会被绑定调用。该属性仅在获取或设置代码时使用
  • Animation 属性不是由绑定设置的。我怎样才能让它发挥作用?
  • 我相信您使用标准的 Property 语法作为 DependencyProperty 的包装器。 getter 很好,但是 setter 应该只调用 SetValue(AnimationProperty, value);
  • 终极面部护理。如果是 DependencyProperty,则不需要实现 INPC。
  • 我将设置器更改为调用 SetValue(AnimationProperty, value) 但仍然无法正常工作。还有什么?

标签: c# wpf mvvm


【解决方案1】:

您需要在控件的代码隐藏中实现DependencyProperty

为控件实现依赖属性后,该属性将在 XAML 中公开。

【讨论】:

  • 嗨,Scott,我确实实现了依赖属性 AnimationProperty。请参阅第二个代码块。并且 Animation 属性被暴露。问题是绑定不起作用。有什么想法吗?
  • 您不需要 SetValueDP。只需使用 SetValue。在您的代码隐藏中删除您的 INotifyPropertyChanged 依赖项。使用 MVVM 将解决您的许多问题。
  • 我在代码隐藏中注释掉了 SetValueDP 并删除了 INotifyPropertyChanged 依赖项。但绑定仍然不起作用?
  • 属性“CpbIsEnabled”与通知属性更改的“CpbEnabled”不匹配
  • 感谢您发现这一点。在代码中更正了它,但绑定仍然不起作用。
【解决方案2】:

我终于想通了。非常感谢所有帮助过的人。

用户控制代码

  <UserControl.Resources>
    <BooleanToVisibilityConverter x:Key="bool2visibility" />
  </UserControl.Resources>
  <Grid>
    <Viewbox>
      <Grid x:Name="LayoutRoot" Background="Transparent" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=IsLoading, Mode=OneWay, Converter={StaticResource bool2visibility}}">
        <Grid.RenderTransform>
          <ScaleTransform x:Name="SpinnerScale" ScaleX="1.0" ScaleY="1.0" />
        </Grid.RenderTransform>
        <Canvas RenderTransformOrigin="0.5,0.5" 
                    HorizontalAlignment="Center" 
                    VerticalAlignment="Center"   
                    Width="120" Height="120" >
          <Ellipse Width="21.835" Height="21.862" 
                  Canvas.Left="20.1696" 
                  Canvas.Top="9.76358" 
                  Stretch="Fill" Fill="Orange" 
                  Opacity="1.0"/>
          <Ellipse Width="21.835" Height="21.862" 
                  Canvas.Left="2.86816" 
                  Canvas.Top="29.9581" Stretch="Fill" 
                  Fill="Black" Opacity="0.9"/>
          <Ellipse Width="21.835" Height="21.862" 
                  Canvas.Left="5.03758e-006" 
                  Canvas.Top="57.9341" Stretch="Fill" 
                  Fill="Black" Opacity="0.8"/>
          <Ellipse Width="21.835" Height="21.862" 
                  Canvas.Left="12.1203" 
                  Canvas.Top="83.3163" Stretch="Fill" 
                  Fill="Black" Opacity="0.7"/>
          <Ellipse Width="21.835" Height="21.862" 
                  Canvas.Left="36.5459" 
                  Canvas.Top="98.138" Stretch="Fill" 
                  Fill="Black" Opacity="0.6"/>
          <Ellipse Width="21.835" Height="21.862" 
                  Canvas.Left="64.6723" 
                  Canvas.Top="96.8411" Stretch="Fill" 
                  Fill="Black" Opacity="0.5"/>
          <Ellipse Width="21.835" Height="21.862" 
                  Canvas.Left="87.6176" 
                  Canvas.Top="81.2783" Stretch="Fill" 
                  Fill="Black" Opacity="0.4"/>
          <Ellipse Width="21.835" Height="21.862" 
                  Canvas.Left="98.165" 
                  Canvas.Top="54.414" Stretch="Fill" 
                  Fill="Black" Opacity="0.3"/>
          <Ellipse Width="21.835" Height="21.862" 
                  Canvas.Left="92.9838" 
                  Canvas.Top="26.9938" Stretch="Fill" 
                  Fill="Black" Opacity="0.2"/>
          <Ellipse Width="21.835" Height="21.862" 
                  Canvas.Left="47.2783" 
                  Canvas.Top="0.5" Stretch="Fill" 
                  Fill="Black" Opacity="0.1"/>
          <Canvas.RenderTransform>
            <RotateTransform x:Name ="SpinnerRotate" Angle = "0" />
          </Canvas.RenderTransform>
          <Canvas.Triggers>
            <EventTrigger RoutedEvent ="ContentControl.Loaded" >
              <BeginStoryboard>
                <Storyboard x:Name="CirccularProgressBarStoryBoard">
                  <DoubleAnimation 
                    Storyboard.TargetName ="SpinnerRotate" 
                    Storyboard.TargetProperty ="(RotateTransform.Angle)" 
                    From="0" To="360" 
                    Duration="0:0:01" 
                    RepeatBehavior="Forever"/>
                </Storyboard>
              </BeginStoryboard>
            </EventTrigger>
          </Canvas.Triggers>
        </Canvas>
      </Grid>
    </Viewbox>
  </Grid>

用户控制代码隐藏。

  public partial class CircularProgressBar : UserControl 
  {
    public static readonly DependencyProperty IsLoadingProperty = DependencyProperty.Register("IsLoading", typeof(bool), typeof(CircularProgressBar), new UIPropertyMetadata(false));
    public bool IsLoading
    {
      get { return (bool)GetValue(IsLoadingProperty); }
      set { SetValue(IsLoadingProperty, value); }
    }

    public CircularProgressBar()
    {
      InitializeComponent();
      (this.Content as FrameworkElement).DataContext = this;
    }
  }

查看xml

<local:CircularProgressBar  x:Name="cpb" IsLoading="{Binding CPBLoading}" >

【讨论】:

    猜你喜欢
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    相关资源
    最近更新 更多