【问题标题】:Replacing UserControl by property按属性替换 UserControl
【发布时间】:2013-03-06 12:50:19
【问题描述】:

我有两个User Control's 坐在主要的UserCotrol 中。

其中只有一个应该是主要的。

当您更改 ViewModel 中的某些属性时,我会这样更改它们:

<UserControl>
    <ContentControl>
        <ContentControl.Style>
            <Style TargetType="{x:Type ContentControl}">
                <Setter Property="Content">
                    <Setter.Value>
                        <local:UserControl1/>
                    </Setter.Value>
                </Setter>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsTwo}" Value="True">
                        <Setter Property="Content">
                            <Setter.Value>
                                <local:UserControl2/>
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ContentControl.Style>
    </ContentControl>
</UserControl>

当我将属性更改为False 时,它会毫无问题地转到UserControl1,但是当我将其更改为True 时,显示会出现问题,并且只有当我在适合的屏幕之间移动时,因为一个临时解决方案,每次 UserControl 应该从 1 更改为 2 时,我都会创建事件。当该事件运行时,我删除主 UserControl 并重新创建它。

但我的问题是,为什么当我更改为一个时我不需要重新创建,而当我更改为两个时我可能需要?

不要给我任何解决这个问题的想法(我自己做过),我想解释为什么会这样,这是我感兴趣的。

【问题讨论】:

  • “显示问题”是什么意思?可以给个截图吗?
  • @DanPuzey,我的意图:它没有像应该显示的那样显示在屏幕上,看起来他被以前的用户控制(UserControl1)卡住了,我也无法访问它了, (点击 UserCotrol 中的按钮不会去任何地方,不是第一个也不是第二个)
  • 如果最小化和恢复窗口,会显示哪个控件?我想知道您的内容是否由于某种原因发生了变化,但窗口没有重新呈现。
  • @DanPuzey,这听起来很有趣,因为当我从第二个移动到第一个时,它会正确显示,但我会检查它。
  • 尝试切换用户控件(首先显示 UserControl2),它在启动时是否正确显示?你的 xaml 对我来说很好用,所以问题很可能出在其他地方。

标签: wpf mvvm binding user-controls


【解决方案1】:

你的 WPF 很好;我无法重现您的问题;启动一个新的 WPF 应用程序并将其转储到其中:然后替换为您的用户控件(请记住,如果您希望它绑定到特定的东西,您可能需要在模板中绑定用户控件)

ViewModel.cs:

public class ViewModel : INotifyPropertyChanged
{
    private bool _isTwo;

    public bool IsTwo
    {
        get { return _isTwo; }
        set
        {
            _isTwo = value;
            OnPropertyChanged("IsTwo");
        }
    }

    public ICommand Switch
    {
        get { return new RelayCommand((_) => { IsTwo = !IsTwo; }, (_) => true); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

public class RelayCommand : ICommand
{
    private readonly Action<object> _action;
    private readonly Func<object, bool> _predicate;

    public RelayCommand(Action<object> action, Func<object, bool> predicate)
    {
        _action = action;
        _predicate = predicate;
    }

    public bool CanExecute(object parameter)
    {
        return _predicate(parameter);
    }

    public void Execute(object parameter)
    {
        _action(parameter);
    }

    public event EventHandler CanExecuteChanged;
}

主窗口

<Window.DataContext>
    <local:ViewModel/>
</Window.DataContext>

<DockPanel>
    <Button DockPanel.Dock="Top" Command="{Binding Switch}"> Switch </Button>
    <UserControl>
        <ContentControl >
            <ContentControl.Style>
                <Style TargetType="{x:Type ContentControl}">
                    <Setter Property="Content">
                        <Setter.Value>
                            <local:UserControl1 DataContext="{Binding UserControl1ViewModel}"/>
                        </Setter.Value>
                    </Setter>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsTwo}" Value="True">
                            <Setter Property="Content">
                                <Setter.Value>
                                    <local:UserControl2/>
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>
        </UserControl>
</DockPanel>

创建两个新的(空的)用户控件并设置两种不同的颜色:

用您遇到问题的用户控制器替换其中之一。如果您有布局问题,您的用户控件很可能正在尝试调整自己的大小,或者您需要将它们放在更好的容器中。我将以上内容粘贴到 DockPanel 中。这通常非常擅长将控件扩展到可用空间。

[编辑]

因此,如果您想知道什么时候创建的,请将这些消息框添加到您的用户控件的 ctor 中

public UserControl1()
{
    InitializeComponent();

    MessageBox.Show("Created UserControl1");
}

public UserControl2()
{
    InitializeComponent();

    MessageBox.Show("Created UserControl2");
}

对我来说,它们都是在应用程序启动时创建的。即 UserControl2 尚不可见,但已创建。有人会认为它在数据触发器切换之前不会被绑定;但是如果你在你的用户控件中做一些代码隐藏,那可能会搞砸 WPF。

【讨论】:

    猜你喜欢
    • 2018-05-30
    • 1970-01-01
    • 2018-05-06
    • 2012-09-11
    • 1970-01-01
    • 2015-03-19
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多