我有一个自定义用户控件,它公开了两个依赖项属性,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>
答案 0 :(得分: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执行相同的操作。希望有所帮助。
答案 1 :(得分:0)
触发器中的绑定对我来说似乎很奇怪。试试这个:
<Trigger Property="IsBusy" Value="true">
<Setter Property="Visibility" Value="Visible" />
<Setter Property="Opacity" Value=".3" />
</Trigger>
当我阅读你的代码时,逻辑对我来说并不完全合理。 0.3不透明度对于必须可见的控件是否足够?请记住通过Controls XAML设置默认行为,并使用触发器仅修改适合该状态的值。
我想说的是你的触发器上的IsEnabled setter。这可能很好地在主UserControl中设置,因为当前控件只能在隐藏控件时被启用,当它被显示为禁用时。
这有意义吗?希望这有帮助!