我正在开发一个自定义面板控件,我试图让它做的一件事就是在运行时交换它的内容。该控件有两种状态:最大化和正常。当用户单击控件上的按钮时,状态会切换。此控件有两个属性:MaximizedContent 和 MinimizedContent。当单击交换状态的按钮时,控件的 Content 属性需要在 MaximizedContent 和 MinimizedContent 之间交换。当 MaximizedContent 或 MinimizedContent 内部存在绑定(bind)时,就会出现问题。它们似乎不是“树”的一部分,因此绑定(bind)不起作用......至少这是我的理论。所以我的问题是如何使它们成为树的一部分?
这是一个简化的示例:
MainWindow.xaml
<Window x:Class="SwappingContentTest.MainWindow"
Loaded="Window_Loaded"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="clr-namespace:SwappingContentTest"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel HorizontalAlignment="Left">
<Button x:Name="swapContentButton"
Click="swapContentButton_Click"
Content="Swap Content" />
<local:SwappableContentControl x:Name="swappableControl">
<local:SwappableContentControl.MaximizedContent>
<StackPanel>
<CheckBox x:Name="maximizedCheckBox"
Content="Maximized CheckBox" />
<Button x:Name="maximizedButton"
Content="Maximized Button"
IsEnabled="{Binding ElementName=maximizedCheckBox, Path=IsChecked}" />
</StackPanel>
</local:SwappableContentControl.MaximizedContent>
<local:SwappableContentControl.MinimizedContent>
<StackPanel>
<CheckBox x:Name="minimizedCheckBox"
Content="Minimized CheckBox" />
<Button x:Name="minimizedButton"
Content="Minimized Button"
IsEnabled="{Binding ElementName=minimizedCheckBox, Path=IsChecked}" />
</StackPanel>
</local:SwappableContentControl.MinimizedContent>
</local:SwappableContentControl>
<CheckBox x:Name="standardCheckBox"
Content="Standard CheckBox"
Margin="0,20,0,0"/>
<Button x:Name="standardButton"
Content="StandardButton"
IsEnabled="{Binding ElementName=standardCheckBox, Path=IsChecked}" />
</StackPanel>
</Window>
MainWindow.cs
namespace SwappingContentTest
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
swappableControl.SwapContent();
}
private void swapContentButton_Click(object sender, RoutedEventArgs e)
{
swappableControl.SwapContent();
}
}
}
SwappableContentControl.cs
namespace SwappingContentTest
{
public class SwappableContentControl : ContentControl
{
public static readonly DependencyProperty MaximizedContentProperty = DependencyProperty.Register("MaximizedContent", typeof(object), typeof(SwappableContentControl));
public static readonly DependencyProperty MinimizedContentProperty = DependencyProperty.Register("MinimizedContent", typeof(object), typeof(SwappableContentControl));
public static readonly DependencyProperty StateProperty = DependencyProperty.Register("State", typeof(SwappableContentControlState), typeof(SwappableContentControl),
new PropertyMetadata(new PropertyChangedCallback(StatePropertyCallback)));
public static void StatePropertyCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
SwappableContentControl control = (SwappableContentControl)d;
if ((SwappableContentControlState)e.NewValue == SwappableContentControlState.Maximized)
{
control.Content = control.MaximizedContent;
}
else
{
control.Content = control.MinimizedContent;
}
}
public object MaximizedContent
{
get { return GetValue(MaximizedContentProperty); }
set { SetValue(MaximizedContentProperty, value); }
}
public object MinimizedContent
{
get { return GetValue(MinimizedContentProperty); }
set { SetValue(MinimizedContentProperty, value); }
}
public SwappableContentControlState State
{
get { return (SwappableContentControlState)GetValue(StateProperty); }
set { SetValue(StateProperty, value); }
}
public void SwapContent()
{
if (State == SwappableContentControlState.Maximized)
{
State = SwappableContentControlState.Normal;
}
else
{
State = SwappableContentControlState.Maximized;
}
}
}
}
这是该项目的链接: http://www.freewebs.com/thrash505/SwappingContentTest.zip
最佳答案
我建议不要交换内容本身,而是在控件中放置两个 ContentControl 实例并更改可见性。除了整体上更干净之外,这还将具有仅更新控件布局而不强制重建树的性能优势。它还意味着两个 ContentControl 始终保留在逻辑树中,使它们更容易在控件实现中引用并保持绑定(bind)正确更新。另外,您还可以获得以下好处:它们可以单独模板化,从而为良好的视觉状态更改打开大门。
关于c# - WPF - 交换 ContentControl(重新链接元素???),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1099530/