1

我有一个自定义用户控件,它公开了两个依赖属性,IsBusy并且BusyText.

我想要的是当 IsBusy 设置为 true 时控件出现...这是用户控件的 xaml

<UserControl x:Class="MyNamespace.BusyDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:MyNamespace"  
Height="Auto" 
Width="Auto"
x:Name="busyControl">
<Grid Panel.ZIndex="10">
    <Border Opacity=".2">
        <Border.Background>
            <RadialGradientBrush>
                <GradientStop Color="#FF000000" Offset="0.59"/>
                <GradientStop Color="#FFB6B6B6" Offset="0"/>
            </RadialGradientBrush>
        </Border.Background>
    </Border>
    <Border VerticalAlignment="Center" 
                    HorizontalAlignment="Center"
                    BorderThickness="2"
                    BorderBrush="Gray">     
        <TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor,
                                                                 AncestorType=controls:BusyDialog},
                                                                 Path=BusyText}"
                   Opacity="1" 
                   Margin="20,10,20,10"/>
    </Border>
    <Grid.Style>
        <Style TargetType="Grid">
            <Setter Property="Visibility" Value="Hidden"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType=controls:BusyDialog},Path=IsBusy}" Value="True">
                    <Setter Property="Opacity" Value=".3" />
                    <Setter Property="IsEnabled" Value="False" />
                    <Setter Property="Visibility" Value="Visible"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Grid.Style>
</Grid>

这是后面的代码

public partial class BusyDialog : UserControl
{
    #region Dependency Properties

    public string BusyText
    {
        get { return (string)GetValue(BusyTextProperty); }
        set { SetValue(BusyTextProperty, value); }
    }

    public bool IsBusy
    {
        get{ return (bool)GetValue(IsBusyProperty); }
        set { SetValue(IsBusyProperty, value); }
    }

    public static readonly DependencyProperty IsBusyProperty =
        DependencyProperty.Register(
            "IsBusy", 
            typeof(bool), 
            typeof(BusyControl), 
            new FrameworkPropertyMetadata(
                false, 
                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

    public static readonly DependencyProperty BusyTextProperty =
        DependencyProperty.Register(
            "BusyText", 
            typeof(string), 
            typeof(BusyControl), 
            new FrameworkPropertyMetadata(
                string.Empty, 
                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
    #endregion

    public BusyDialog ()
    {
        InitializeComponent();
    }
}

这是我在视图中创建用户控件:

<localControls:BusyDialog x:Name="busyControl"
                               Grid.Row="0" 
                               IsBusy="{Binding IsWorking}"
                               BusyText="{Binding WorkingText}">
</localControls:BusyDialog>

我的代码有什么问题吗?每当我在 ViewModel 中设置 IsWorking 属性时,控件都不会按预期显示!

我还尝试像这样设置用户控件绑定:

<UserControl x:Class="MyNamespace.BusyDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:MyNamespace"  
Height="Auto" 
Width="Auto"
x:Name="busyControl">
<Grid Panel.ZIndex="10">
    <Border Opacity=".2">
        <Border.Background>
            <RadialGradientBrush>
                <GradientStop Color="#FF000000" Offset="0.59"/>
                <GradientStop Color="#FFB6B6B6" Offset="0"/>
            </RadialGradientBrush>
        </Border.Background>
    </Border>
    <Border VerticalAlignment="Center" 
                    HorizontalAlignment="Center"
                    BorderThickness="2"
                    BorderBrush="Gray">     
        <TextBlock Text="{Binding ElementName=busyControl, Path=BusyText}"
                   Opacity="1" 
                   Margin="20,10,20,10"/>
    </Border>
    <Grid.Style>
        <Style TargetType="Grid">
            <Setter Property="Visibility" Value="Hidden"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding ElementName=busyControl,Path=IsBusy}" Value="True">
                    <Setter Property="Opacity" Value=".3" />
                    <Setter Property="IsEnabled" Value="False" />
                    <Setter Property="Visibility" Value="Visible"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Grid.Style>
</Grid>

4

2 回答 2

2

您需要在视图模型中实现 INotifyPropertyChanged。

public class WorkingViewModel : INotifyPropertyChanged
{
    // ...

    private bool _isWorking;
    public bool IsWorking
    {
        get{ return _isWorking; }
        set {
                _isWorking = value;
                RaisePropertyChanged("IsWorking");
            }
    }

    // ...
    /// <summary>
    /// Occurs when a property value changes.
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string propertyName)
    {
        if(PopertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    // ...
}

这样,当您的 IsWorking 更改时,它将更新您的 BusyDialog 控件中的 IsBusy。

<localControls:BusyDialog x:Name="busyControl"
                               Grid.Row="0" 
                               IsBusy="{Binding IsWorking}"
                               BusyText="{Binding WorkingText}">
</localControls:BusyDialog>

如果您也打算更改它,请确保对您的 WorkingText 执行相同的操作。希望有帮助。

于 2009-10-23T02:28:42.887 回答
0

触发器中的绑定对我来说似乎很奇怪。尝试这个:

<Trigger Property="IsBusy" Value="true">
    <Setter Property="Visibility" Value="Visible" />
    <Setter Property="Opacity" Value=".3" />
</Trigger>

当我阅读您的代码时,逻辑对我来说并不完全有意义。对于必须可见的控件,0.3 不透明度是否足够?请记住通过控件 XAML 设置默认行为,并使用触发器仅修改适合该状态的值。

我想说的一个例子是触发器上的 IsEnabled 设置器。这很可能在主用户控件中设置,因为当前控件只能在控件隐藏时启用,当它显示时它被禁用。

这有意义吗?希望这可以帮助!

于 2009-10-16T06:54:23.730 回答