WPF绑定用户控件

时间:2011-01-24 20:17:26

标签: c# wpf binding tabcontrol

好的,所以我创建了两个东西,MainWindowViewModel和TabControlViewModel。在我的TabControlViewModel中,我的View基本上是一个带有3个tabitems的TabControl(Welcome / tabItem1 / tabItem2)。

我的目标是当应用程序启动时我只看到欢迎选项卡,然后当我选择文件 - >打开两个tabItems变得可见,焦点显示我的tabItem2显示文本文件内容。

MainWindow.Xaml

<Menu DockPanel.Dock="Top" Width="Auto" Height="25" Name="Menu1">
                <MenuItem Header="_File" VerticalContentAlignment="Top" >
                    <MenuItem Header="_New" Command="{Binding NewCommand}" />
                    <MenuItem Header="_Open" Command="{Binding OpenCommand}">

TabControlViewModel.cs

class TabControlViewModel : TabContainer
{

   private DelegateCommand openCommand;
    public ICommand OpenCommand
    {
        get
        {
            if (openCommand == null)
                openCommand = new DelegateCommand(Open);
            return openCommand;
        }
    }

    private void Open(object obj)
    {
        ProcessOpenCommand();
    }

    private void ProcessOpenCommand()
    {
        if (dataChanged)
        {
            SaveFirst();
            ShowOpenDialog();

        }
        else
        {
            ShowOpenDialog();

        }
    }

    private void ShowOpenDialog()
    {
        System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();
        ofd.Filter = "Text File (*.txt)|*.txt";

        if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            filePath = ofd.FileName;
            ReadFile(filePath);
            SetTitle(ofd.SafeFileName);
            RuleTab.Focus();
        }
    }

    private string SaveFirst()
    {
        MessageBoxResult mbr = System.Windows.MessageBox.Show("Do you want to save changes?", "Save Changes", MessageBoxButton.YesNoCancel, MessageBoxImage.Warning);

        if (mbr == MessageBoxResult.Yes)
        {
            if (filePath != null)
            {
                SaveFile(filePath);
            }
            else
            {
                ProcessSaveCommand();
            }
        }
        else if (mbr == MessageBoxResult.Cancel)
        {
            return "Cancel";
        }
        return "Nothing";
    }

我想我最大的问题是,我的菜单命令应该在这个TabControlViewModel中还是在我的MainWindowViewModel中?非常感谢你们在这里耐心等待...... :)

3 个答案:

答案 0 :(得分:0)

您可以使用DependencyProperty some tutorial在自定义控件上创建ItemsSource属性 然后绑定到它就像你在默认控件上做的那样。

MyTabControl的代码(我假设所有选项卡都是在InitializeComponent之后生成的 - 在Xaml中创建,所以如果你以后添加任何新的,你需要更新属性):

public partial class MyTabControl
{
    public static readonly DependencyProperty ItemsProperty =
       DependencyProperty.Register(
       "Items",
       typeof(IEnumerable),
       typeof(MyTabControl),
       null);

    public IEnumerable Items
    {
        get { return (IEnumerable)GetValue(ItemsProperty); }
        set { SetValue(ItemsProperty, value); }
    }

    public MyTabControl()
    {
        InitializeComponent();
        Items = tabControl.Items;
    }
}

这段代码没有任何问题,但在某些时候,你可以在mvvm上投入一些时间,因为在很多情况下它会更容易。

答案 1 :(得分:0)

如果您使用mvvm-light框架(http://mvvmlight.codeplex.com/),则可以让控件1在双击项目时广播消息。然后让控件2订阅该类型的消息。当它收到消息时,它可以将Datacontext设置为正确的值。这当然假设您正在使用mvvm,并且每个usercontrol都有自己的viewmodel。

广播代码可能如下所示:

public class MainViewModel
{
    public RelayCommand myCommand { get; private set; }
    public MainViewModel()
    {
        myCommand = new RelayCommand( () => SendTheMessage());
    }
    public void SendTheMessage()
    {
        Messenger.Default.Send("I have sent the message");
    }
}

接收者代码看起来像这样:

    public class myModel
    {
        public myModel()
        {
            Messenger.Default.Register<string>(this, DoSomething);
        }

        public void DoSomething(string item)
        {
            System.Windows.MessageBox.Show(item);
        }
    }

答案 2 :(得分:0)

  

我一直在阅读视图模型,并不认为这是我的简单应用程序所必需的。

你几乎肯定在这里弄错了。

事实上,如果您正在使用视图模型,那么您在此处尝试的操作非常简单:不是编码控件之间的相互关系,而是构建视图模型对象的集合,即ItemsSource的选项卡控件和列表框。

如果要双击列表框中的项目以执行影响选项卡控件中显示内容的操作,请在视图模型中实现命令并双击该项执行命令。该命令执行后,它会对视图模型进行任何更改,更改的属性会引发其事件,并且选项卡控件中的显示会发生更改。

这不仅可以为单元测试编写(这是另一个主题),它还可以将列表框和选项卡控件相互分离。例如,您可以决定将Tab控件替换为其他类型的项控件(如Telerik RadPanelBar),而不必更改任何代码。您可以这样做,因为视图模型是视图的逻辑模型,它与任何视图的实现细节都是隔离的。

不要害怕视图模型。他们真的不复杂。必须实施属性更改通知有点烦人,但在一天结束时,为一致,简单,灵活的软件付出的代价非常小。