我有一个自定义控件,它有一个按钮:
<UserControl x:Class="Gambit.Views.FileSelectionControl"
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"
SnapsToDevicePixels="True"
mc:Ignorable="d">
...
<Button Content="Load"
Margin="5,5,5,5"
Height="22"
Width="70"
IsDefault="True"
IsEnabled="{Binding SelectedFileExists}"
AttachedCommand:CommandBehavior.Event="Click"
AttachedCommand:CommandBehavior.Command="{Binding CloseDialogCommand}"/>
...
</UserControl>
我想在另一个控件中包含此控件,但我想在主机控件中设置Load
按钮的可见性;
<UserControl x:Class="Gambit.Views.SomeOtherControl"
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"
SnapsToDevicePixels="True"
mc:Ignorable="d">
...
<GroupBox Header="Select Test Data">
<Views:FileSelectionControl <Here Set the Load Button Visibility>/>
</GroupBox>
...
</UserControl>
其中<Here Set the Load Button Visibility>
显示我想要设置控件可见性的位置。如何完成[不破坏MVVM模式]?
感谢您的时间。
答案 0 :(得分:5)
您可以在DependencyProperty
:
UserControl
public partial class SomeView : UserControl
{
...
public static DependencyProperty ButtonVisibilityProperty = DependencyProperty.Register("ButtonVisibility", typeof(Visibility), typeof(SomeView));
public Visibility ButtonVisibility
{
get { return (Visibility)GetValue(ButtonVisibilityProperty); }
set { SetValue(ButtonVisibilityProperty, value); }
}
}
将其绑定到Button.Visibility
:
<UserControl x:Class="WpfApplication2.SomeView"
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">
<Button Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=ButtonVisibility}" Content="My Button"/>
</UserControl>
然后你就可以从外面控制Visibility
:
<local:SomeView ButtonVisibility="Collapsed"/>
因为它是DependencyProperty
,您也可以使用Binding
答案 1 :(得分:2)
您只需在UserControl1中创建一个bool或Visibility Type属性,并将其设置为Usercontrol2,如
UserControl1 xaml
<UserControl x:Class="WpfApplication4.UserControl1"
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="300" d:DesignWidth="300">
<Grid>
<Button x:Name="Loadbutton" Content="load"/>
</Grid>
xaml.cs
public UserControl1()
{
InitializeComponent();
}
bool showLoadButton;
public bool ShowLoadButton
{
get { return showLoadButton; }
set
{
showLoadButton = value;
if (showLoadButton)
Loadbutton.Visibility = Visibility.Visible;
else
Loadbutton.Visibility = Visibility.Collapsed;
}
}
UserControl2将ShowLoadButton设置为True或false
<UserControl x:Class="WpfApplication4.UserControl2"
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"
xmlns:local="clr-namespace:WpfApplication4"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<local:UserControl1 ShowLoadButton="True"/>
</Grid>
答案 2 :(得分:1)
如果您不想在UserControl
中定义属性,您可以随时创建附加依赖项属性,并且可以在公共名称空间下的单独类中声明它。
这样的事情:
MainWindow.xaml
<local:TestUserControl AttachedProperties:ButtonExt.Visibility="Visible" />
TestUserControl.xaml
<Button Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}},
Path=(AttachedProperties:ButtonExt.Visibility)}"
Content="TestButton" />
附属物定义:
public static class ButtonExt
{
public static readonly DependencyProperty VisibilityProperty;
public static void SetVisibility(DependencyObject DepObject, Visibility value)
{
DepObject.SetValue(VisibilityProperty, value);
}
public static Visibility GetVisibility(DependencyObject DepObject)
{
return (Visibility)DepObject.GetValue(VisibilityProperty);
}
static ButtonExt()
{
PropertyMetadata VisibiltyPropertyMetadata = new PropertyMetadata(Visibility.Collapsed);
VisibilityProperty = DependencyProperty.RegisterAttached("Visibility",
typeof(Visibility),
typeof(ButtonExt),
VisibiltyPropertyMetadata);
}
}
<强> Some notes about code-behind in MVVM
强>
我同意@dkozl,他的例子没有违反MVVM的原则,在某些情况下,代码存在于View
中,例如(个人而言,我总是试图避免代码隐藏):
安装DataContext
。
使用不同的模式,如Mediator,Proxy等
确定仅与View
相关的属性和行为(如您的情况)。
当您使用代码隐藏时最重要的事情是,ViewModel
发生了所有可能的操作,即在ViewModel
中包含所有逻辑,例如View
点击事件,调用ViewModel
中的函数。
有关代码隐藏的详细信息,请参阅最近问题的答案: